简体   繁体   中英

Java - Assistance with understanding codility code

For the PermCheck codility test, I coded one solution (please see below) but it only really solved the example given in the codility test because there are only a few values in the array and small values. I also added code below which scored 100%, which is code I found on the internet. That code looks very different from mine and I couldn't work out how he/she was able to get the answer. Could someone please explain the code step by step and how it results in the answer please.

Codility Test:

PermCheck

Check whether array A is a permutation.

A non-empty zero-indexed 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:

class Solution {
    public int solution(int[] A);
}

that, given a zero-indexed 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.

Assume that:

  • 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].

Complexity:

  • Expected worst-case time complexity is O(N)
  • Expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
  • Elements of input arrays can be modified.

100% Score Solution (found from internet):

public static final int NOT_PERMUTATION = 0;
public static final int PERMUTATION = 1;
// (4,1,3,2) = 1
// (4,1,3) = 0
// (1) = 1
// () = 1
// (2) = 0
public int PermSolution(int[] A) {
    // write your code in Java SE 8
    int[] mark = new int[A.length + 1];
    int counter = 0;

    for (int i = 0; i < A.length; ++i) {
        int value = A[i];
        if(value >= mark.length) {
            return NOT_PERMUTATION;
        }
        if(mark[value] == 0) {
            mark[value]=1;
            ++counter;
        } else {
            return NOT_PERMUTATION;
        }
    }

    return counter == A.length ? PERMUTATION : NOT_PERMUTATION;
}

My Solution:

public int PermSolution(int[] A)
{
    int perm = 1;

    Arrays.sort(A);

    if (A[0] != 1) return 0;

    for (int i = 0; i < A.length; i++)
    {
        if (A[i] + 1 == A[i + 1])
        {
            return perm;
        }

        if (A[i] + 1 != A[i + 1])
        {
            return 0;
        }
    }

    return perm;

}

Using Arrays.sort() is kind of original, that's not how I would have done it though.

To comment your code, it's probably isn't working because of this : return perm;

Let's say you have this Array which is not a permutation:

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

One you execute Arrays.sort(A) , you'll have this :

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

Now let's execute your code :

if (A[0] != 1) return 0;

A[0] is indeed equal to 1 Next, for i==0 we have :

  if (A[i] + 1 == A[i + 1])
    {
        return perm;
    }

A[i] + 1 is equal 2 and A[i+1] is also equal to 2 the condition being true , you execute a return perm; and thus, you end your execution with a return 1 .

Actually, as long as your array contains 1 and 2 , this function will always return 1

For it to work, you'll have to check all of the array before actually returning a value.

This should work :

public int PermSolution(int[] A)
{

int perm = 1;
Arrays.sort(A);

if (A[0] != 1) return 0;

for (int i = 0; i < A.length; i++)
{
       if (A[i] + 1 != A[i + 1])
    {
        return 0;
    }
}

return perm;

}

To optimize it even further, this should work as well :

public int PermSolution(int[] A)
    {

    Arrays.sort(A);

    for (int i = 0; i < A.length; i++)
    {
           if (A[i] != i+1)
        {
            return 0;
        }
    }

    return 1;

    }

Why don't we avoid Arrays.sort(A) in order to gain the computation efficiency by below:

public static int PermSolution(int[] A)
{
    int len=A.length;
    if(len==1)
        return A[0]==1 ? 1 : 0;

    BitSet set=new BitSet(len+2);

    for (int i = 0; i < len; i++)
    {
        if(A[i]>len || set.get(A[i]))
            return 0;

        set.set(A[i]);
    }
    return set.nextClearBit(1)==(len+1) ? 1 : 0;
}

Here is some solution that I have developed. Not sure about constraints, if someone can help to test it against them. Thanks people!

private static int solution(int[] arr) {

        int perm=1;
        boolean b=false;
        Arrays.sort(arr);
        int i=0;
        while (i<=arr.length) {
            if(i < arr.length-2)
                b = arr[i+1]-1 == (arr[i]);
            if(b) {
                System.out.println("if " + i);
                i++;
                perm=1;
            }else {
                System.out.println("else " + i);
                perm = 0;
                break;
            }
        }   
        return perm;
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM