我正在努力解决以下问题'锻炼:
给出了由N个不同整数组成的零索引数组A.该数组包含[1 ..(N + 1)]范围内的整数,这意味着只缺少一个元素。
您的目标是找到缺少的元素。
写一个函数:
class Solution { public int solution(int[] A); }
给定零索引数组A,返回缺少元素的值。
例如,给定数组A使得:
A[0] = 2
A[1] = 3
A[2] = 1
A[3] = 5
该函数应该返回4,因为它是缺少的元素。
假设:
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)].
复杂度:
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).
可以修改输入数组的元素。
我想出了两个解决方案:
1)给予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)发出错误错误答案,得到65536预期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;
}
}
我的问题是: 两种方法(使用hashset和Arrays.sort)都不应该以相同的方式工作吗? 如果没有,你能告诉我有什么区别吗?
答案 0 :(得分:0)
HashSet
未排序,因此当您迭代Set的元素时,您不会按照代码期望的升序获取它们。如果您使用的是TreeSet
而不是HashSet
,那么您的代码就可以使用。
如果您将第二个循环更改为:
,HashSet
解决方案将给出正确答案
for (int i = 0; i <= A.length; i++) {
if (!hs.contains(i)) {
return i;
}
}
此循环显式检查相关范围中的每个整数是否出现在HashSet
中,并返回第一个(且只有一个)不存在的整数。
无论如何,您的实施都不符合O(n)
运行时间和O(1)
空间要求。
为了满足所需的运行时间和空间,您应该计算数组元素的总和,并从(A.length+1)*A.length/2
中减去该总和。