Categories
coding solutions

Codility: PermCheck Solution

PermCheck Solution

Task

The task is to calculate if an array contains all the numbers from 1 to N, where N is the size of the array:

A non-empty array A consisting of N integers is given.

A permutation is a sequence containing each element from 1 to N once, and only once.

For example, array A such that:

A[0] = 4 A[1] = 1 A[2] = 3 A[3] = 2

is a permutation, but array A such that:

A[0] = 4 A[1] = 1 A[2] = 3

is not a permutation, because value 2 is missing.

The goal is to check whether array A is a permutation.

Write a function:int solution(vector<int> &A);

that, given an array A, returns 1 if array A is a permutation and 0 if it is not.

For example, given array A such that:

A[0] = 4 A[1] = 1 A[2] = 3 A[3] = 2

the function should return 1.

Given array A such that:

A[0] = 4 A[1] = 1 A[2] = 3

the function should return 0.

Write an efficient algorithm for the following assumptions:

  • N is an integer within the range [1..100,000];
  • each element of array A is an integer within the range [1..1,000,000,000].

Solution 1

The naive solution of searching for each number [1..N] in the array would be O(N2).
The most time efficient solution is to use a bit map, this is O(N).
#include <iostream> using namespace std; #include <bitset> #include <vector> #define SIZEA 1000000000 int solution(vector<int> &A) { auto pbits = new bitset<SIZEA>; pbits->reset(); for (size_t i = 0; i < A.size(); i++) { int el = A[i]; if ((*pbits)[el]) { return 0; } (*pbits)[el] = true; } for (uint i = 0; i < A.size(); i++) { if (!(*pbits)[i+1]) { return 0; } } return 1; }
Line 9 would be a memory leak if the function was called repeatedly.

Results

Codility Results

Correctness100%
Performance100%
Time ComplexityO(N)

Solution 2

An even simpler solution is to first sort the array. This is O(N*log(N)), but also passes the performance test.
int solution(vector<int> &A) { std::sort(std::begin(A), std::end(A)); for (size_t i = 0; i < A.size(); i++) { if(A[i] != i+1) return 0; } return 1; }

Results

Correctness100%
Performance100%
Time ComplexityO(N*log(N))

Test Function

This code tests the solution

int main() { vector<int> v1{4, 1, 3, 2}; assert(solution(v1) == 1); vector<int> v2{4, 1, 3}; assert(solution(v2) == 0); vector<int> v3{4, 1, 3,3,2}; assert(solution(v3) == 0); vector<int> v4{1}; assert(solution(v4) == 1); vector<int> v5{2}; assert(solution(v5) == 0); vector<int> v6{12, 9, 3, 2}; assert(solution(v6) == 0); return 0; }

Other Solutions

These are some other solutions to this problem on the web

This blog has an apparently clever solution:

int solution(vector<int> &v) { unsigned xorsum = 0; int v_size = v.size(); for (size_t i = 0; i < v_size; i++) { xorsum = (i + 1) ^ static_cast<unsigned>(v[i]) ^ xorsum; } return xorsum == 0; }
This works (mostly) because:
  • XORing a number with itself = 0
  • XOR is commutative, so a ^ b ^ c ⇔ c ^ b ^ a
And so xorsum ⇔ (1 ^ v[a] ) ^ (2 ^ v[b]) ^ … for every possible permutation of a,b,c, …
So if a permutation exists for which v[a]=1, v[b]=2 etc, then xorsum == 0
However, there are other arrays for which xorsum also == 0. For example, this solution fails the test above with array v6.
The Codility tests do not contain any test data for which this fails, so it passes the test with 100% correctness.
Correctness100%
Performance100%
Time ComplexityO(N)

These blogs also have some variation of the bit set solution above

Index of solutions to Codility Lessons

Leave a Reply

Your email address will not be published. Required fields are marked *