二进制搜索实现条件混乱

时间:2019-09-07 22:30:57

标签: binary-search

我正在使用二进制搜索解决问题,当我看到人们在某些地方使用while start < end时感到困惑,但是在算法中,我的理解是应该使用while start <= end

例如,这是Leetcode问题的一种解决方法查找大于目标的最小字母

def nextGreatestLetter (self, letters: List[str], target: str) -> str:
    l, r = 0, len(letters)-1

    # cross the border
    if target >= letters[-1]:
        return letters[0]

    while l < r:
        mid = (l+r)//2
        if letters[mid] <= target:
            l = mid+1
        else:
            r = mid
    return letters[l]

为什么我们不递减r = mid - 1?为什么不递减while l <= r?  我真的很困惑。

1 个答案:

答案 0 :(得分:0)

这些是实现细节。有多种实现所有内容的方法。

在这种情况下,循环条件是l < r(不是l <= r),因为当l == r(即搜索空间中只有一个元素)时,我们不必处理此外,预期结果(ceil)是位置l上的元素。

并且更新语句为r = mid(而不是r = mid - 1),因为该更新是在target < letters[mid]时发生的,因此我们不能根据此条件在中间丢弃该元素。假设例如(mid-1)处的元素小于或等于目标,在这种情况下,我们的结果将是 mid 处的元素。

就像我说的,这些只是实现细节,同样的解决方案也可以像这样实现:

def nextGreatestLetter (self, letters: List[str], target: str) -> str:
    l, r = 0, len(letters)-1

    # cross the border
    if target >= letters[-1]:
        return letters[0]

    while l <= r:
        mid = (l+r)//2
        if letters[mid] <= target:
            l = mid+1
        else:
            r = mid - 1
    return letters[l]

我们在循环内处理l == r情况的实现也是正确的,并将所有测试用例传递给Leetcode。

PS: 我假设您最近开始进行具有竞争力的编码,所以对您来说只是一个建议。再次,不要尝试记住实现并专注于算法的关键,因为再次实现同一算法有多种方式。