简体   繁体   中英

Java hashset vs Arrays.sort

I am trying to solve the below 'codility' exercise:

A zero-indexed array A consisting of N different integers is given. The array contains integers in the range [1..(N + 1)], which means that exactly one element is missing.

Your goal is to find that missing element.

Write a function:

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

that, given a zero-indexed array A, returns the value of the missing element.

For example, given array A such that:

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

the function should return 4, as it is the missing element.

Assume that:

    N is an integer within the range [0..100,000];
    the elements of A are all distinct;
    each element of array A is an integer within the range [1..(N + 1)].

Complexity:

    expected worst-case time complexity is O(N);
    expected worst-case space complexity is O(1), beyond input storage (not counting the storage required for input arguments).

Elements of input arrays can be modified.

I came up with two solutions:

1) Gives 100%/100%

class Solution {

    public int solution(int[] A) {
        int previous = 0;
        if (A.length != 0) {
            Arrays.sort(A);
            for (int i : A) {
                if (++previous != i) {
                    return previous;
                }
            }
        }
        return ++previous;
    }
}

2) Gives an error WRONG ANSWER, got 65536 expected 100001

class SolutionHS {

    public int solution(int[] A) {
        int previous = 0;
        HashSet<Integer> hs = new HashSet<>();
        if (A.length != 0) {
            for (int a : A) {
                hs.add(a);
            }

            for (Integer i : hs) {
                if (++previous != i) {
                    return previous;
                }
            }
        }
        return ++previous;
    }
}

My question is: Shouldn't both approaches (using hashset and Arrays.sort) work the same way? If not can you tell me what the difference is?

HashSet is not sorted, so when you iterate over the elements of the Set, you don't get them in an ascending order, as your code expects. If you used a TreeSet instead of HashSet , your code would work.

The HashSet solution will give the correct answer if you change the second loop to :

for (int i = 0; i <= A.length; i++) {
    if (!hs.contains(i)) {
        return i;
    }
}

This loop explicitly checks whether each integer in the relevant range appears in the HashSet and returns the first (and only one) which doesn't.

Anyway, both your implementations don't meet the O(n) running time and O(1) space requirements.

In order you meet the required running time and space, you should calculate the sum of the elements of the array and subtract that sum from (A.length+1)*A.length/2 .

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