二次搜索第一次出现k

时间:2017-10-17 17:18:50

标签: algorithm binary-search

我有代码搜索已排序的数组并返回第一次出现的k的索引。 我想知道是否可以使用

编写此代码
while(left<right) 

而不是

while(left<=right)

以下是完整代码:

public static int searchFirstOfK(List<Integer> A, int k) {
   int left = 0, right = A.size() - 1, result = -1;
   // A.subList(left, right + 1) is the candidate set.
   while (left <= right) {
      int mid = left + ((right - left) / 2);
      if (A.get(mid) > k) {
         right = mid - 1;
      } else if (A.get(mid) == k) {
         result = mid;
         // Nothing to the right of mid can be the first occurrence of k.
         right = mid - 1;
      } else { // A.get(mid) < k
         left = mid + 1;
      }
   }
   return result;
}

我如何知道何时使用左边小于或等于右边,或者只是使用左边小于右边。

3 个答案:

答案 0 :(得分:2)

简单地说没有。

考虑数组只有一个元素的情况,即{0},并且要搜索的元素也是0

在这种情况下,left == right,但如果您的条件为while(left<right),则searchFirstOfK将返回-1

此答案取决于发布的代码。如果我们正在谈论替代方案以便我们可以使用while(left<right)那么Matt Timmermans的答案是正确的,并且是一种更好的方法。

下面是Matt的comparison(OP - 我们称之为Normal Binary)和Matt Timmermans(让我们称之为Optimized Binary)方法,列出包含0到5000000之间值的列表:

Binary Algorithm Comparison

答案 1 :(得分:2)

基于对另一个二进制搜索问题的答案:How can I simplify this working Binary Search code in C?

如果要查找第一次出现的位置,则在找到匹配的元素时无法停止。您的搜索应该如下所示(当然这假定列表已排序):

int findFirst(List<Integer> list, int valueToFind)
{
    int pos=0;
    int limit=list.size();
    while(pos<limit)
    {
        int testpos = pos+((limit-pos)>>1);

        if (list.get(testpos)<valueToFind)
            pos=testpos+1;
        else
            limit=testpos;
    }
    if (pos < list.size() && list.get(pos)==valueToFind)
        return pos;
    else
        return -1;
}

请注意,我们每次迭代只需要进行一次比较。二进制搜索找到所有前面的元素小于valueToFind并且所有以下元素都大于或等于的唯一位置,然后然后它检查您的值是否为&#39;正在寻找的确实存在。

链接的答案强调了以这种方式编写二进制搜索的几个优点。

答案 2 :(得分:0)

这是一个非常有趣的问题。事情就是有一种方法可以让你的二进制搜索始终正确。问题在于确定正确的范围并避免单个元素突出行为。

while(left+1<right)
{
   m = (left+right)/2;
   if(check condition is true)
      left = m;
   else
      right =  m;
}

唯一要记住的关键是你总是将左边视为最不满意元素的最小条件,并且是满足元素的最大条件。这样你就不会被困住。一旦你通过这种方法理解了范围划分,你就不会在二进制搜索中失败。

上面的初始化将为您提供满足元素的最大条件。

通过更改初始化,您可以获得各种元素(例如满足元素的小条件)。