在具有重复

时间:2017-03-04 18:49:41

标签: arrays algorithm binary-search

给定带有可能重复的整数排序数组,如何找到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 - 检查中间元素是否为答案的恒定时间)

这比简单的线性扫描更好吗?这似乎过于复杂,只是为了实现线性时间效率。我在这里错过了什么吗?

1 个答案:

答案 0 :(得分:5)

不,你没有遗漏任何东西。第一个分支有一个短路,但最坏的情况是两次调用都会产生,这会导致线性时间重复。

实际上,这个问题没有通过简单的单元探测下限的次线性时间算法。考虑数组族a其中

a(i) = i + 1 for i ≠ j
a(j) = j
某些j

。这些数组只能通过检查作为固定点的特定条目来区分,这意味着n - 1探针的下限。

我假设的原始CTCI问题不允许重复 - 然后修改后的数组a(i) - i不减少,这允许二元搜索零元素。