这是一个面试问题,但我无法及时解决,所以在此发布:
给定n个整数的排序数组,其中每个整数的范围为0到m-1
和m > n
。找到数组中缺少的最小数字。
实例
输入:{0, 1, 2, 6, 9}
,n = 5
,m = 10
输出:3
输入:{4, 5, 10, 11}
,n = 4
,m = 12
输出:0
此代码如下:
int findFirstMissing(int array[], int start, int end) {
if(start > end)
return end + 1;
if (start != array[start])
return start;
int mid = (start + end) / 2;
if (array[mid] > mid)
return findFirstMissing(array, start, mid);
else
return findFirstMissing(array, mid + 1, end);
}
现在,问题是输入数组也可能有重复项:
input = [0, 1, 1, 2, 3, 3, 4, 5, 5, 7]
output = 6
如何有效地解决问题?可以应用哪种优化?
答案 0 :(得分:0)
可以很容易地证明你在O(n)时间内必须这样做,因为你无法在不检查每个值的情况下区分两个表:
1,2,_3_,4,5,7
和
1,2,_2_,4,5,7
答案 1 :(得分:0)
此解决方案适用于O(N)
时间,并使用O(1)
额外内存:
public class Test {
public static void main(String[] args) {
int m = 5;
int[] data = new int[] {0, 1, 1, 2, 3, 3, 4, 5};
int current = 0;
for (int i = 0; i < data.length; ++i) {
if (current == data[i]) {
current++;
}
}
if (current >= m) {
System.out.println("All is here");
} else {
System.out.println(current);
}
}
}
注意:n
实际上已被忽略,我改为使用data.length
。
答案 2 :(得分:0)
解决方案
public static void main(String[] args) {
Collection<Integer> input = new LinkedList<Integer>(Arrays.asList(10, 9, 7, 6, 5, 4, 3, 2, 1));
NavigableSet<Integer> sortedOriginal = new TreeSet<Integer>(input);
NavigableSet<Integer> numbers = new TreeSet<Integer>();
for(int i=sortedOriginal.first();i<=sortedOriginal.last();i++){
numbers.add(i);
}
for(Integer x : numbers){
if(!sortedOriginal.contains(x)){
System.out.println(x);
break;
}
}
}