【问题标题】:Finding A[i]=i in a sorted array with duplicates在具有重复项的排序数组中查找 A[i]=i
【发布时间】:2017-07-24 19:22:12
【问题描述】:

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

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

【问题讨论】:

  • @HenkHolterman:如果left
  • 是的,它比常规的二分搜索要复杂一些。我读错了那部分。
  • 除非您只关注最坏情况的行为,否则这仍然比简单的线性扫描更好,因为它通常可以亚线性执行。

标签: arrays algorithm binary-search


【解决方案1】:

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

事实上,这个问题没有通过简单的细胞探测下界的亚线性时间算法。考虑数组系列a where

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

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

我假设的原始 CTCI 问题不允许重复 - 然后修改后的数组 a(i) - i 是非递减的,它允许对零元素进行二进制搜索。

【讨论】:

  • 是的,问题的原始版本只有不同的元素
猜你喜欢
  • 1970-01-01
  • 2012-11-17
  • 2016-01-08
  • 1970-01-01
  • 1970-01-01
  • 2011-07-24
  • 2015-08-26
  • 2012-10-20
  • 2020-06-21
相关资源
最近更新 更多