给定带有可能重复的整数排序数组,如何找到i
A[i]=i
这是我读过的一本编程书籍中的一个问题(Cracking the code interview)。解决方案概述如下:
public static int magicFast(int[] array, int start, int end) {
if (end < start || start < 0 || end >= array.length) {
return -1;
}
int midlndex = (start + end) / 2;
int midValue = array[midlndex];
if (midValue == midlndex) {
return midlndex;
}
/* Search left */
int leftlndex = Math.min(midlndex - 1, midValue);
int left = magicFast(array, start, leftlndex);
if (left >= 0) {
return left;
}
/* Search right */
int rightlndex = Math.max(midlndex + i, midValue);
int right = magicFast(array, rightlndex, end);
return right;
}
作者没有评论时间复杂性。然而,这似乎是O(n)解决方案,因为我们需要看看中间的两个方面。与数组元素不同的问题不同。递归关系为T(n)= 2T(n / 2)+ c(c - 检查中间元素是否为答案的恒定时间)
这比简单的线性扫描更好吗?这似乎过于复杂,只是为了实现线性时间效率。我在这里错过了什么吗?
答案 0 :(得分:5)
不,你没有遗漏任何东西。第一个分支有一个短路,但最坏的情况是两次调用都会产生,这会导致线性时间重复。
实际上,这个问题没有通过简单的单元探测下限的次线性时间算法。考虑数组族a
其中
a(i) = i + 1 for i ≠ j
a(j) = j
某些j
的。这些数组只能通过检查作为固定点的特定条目来区分,这意味着n - 1
探针的下限。
我假设的原始CTCI问题不允许重复 - 然后修改后的数组a(i) - i
不减少,这允许二元搜索零元素。