力扣-704-二分查找

发布时间 2023-11-14 14:09:49作者: 王寄鱼

一、题目

力扣链接:https://leetcode.cn/problems/binary-search/description/

二、解法思路

标准的二分查找题目,常规上有左闭右闭和左闭右开的解法

1、左闭右闭

class Solution:
    """
    leetcode:704
    采用左闭右闭的方式,[left,right]
    区间的定义这就决定了二分法的代码应该如何写,因为定义target在[left, right]区间,所以有如下两点:
        1、while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
        2、if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1
    """

    def search(self, nums: List[int], target: int) -> int:
        if target not in range(1, 10000):
            return -1
        if not nums:
            return -1
        left = 0
        right = len(nums) - 1
        while left <= right:
            middle = left + ((right - left) >> 1)
            if nums[middle] == target:
                return middle
            elif nums[middle] > target:
                right = middle - 1
            else:
                left = middle + 1
        else:
            return -1
          
if __name__ == '__main__':
    s = Solution()
    res = s.search(nums=[-1, 0, 3, 5, 9, 12, 37], target=12)
    print(res)

2、左闭右开

class Solution:
    """
    leetcode:704
    采用左闭右开的方式,[left,right)
    如果说定义 target 是在一个在左闭右开的区间里,也就是[left, right) ,那么二分法的边界处理方式则截然不同。
    有如下两点:
        1、while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的
        2、if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]
    """

    def search(self, nums: List[int], target: int) -> int:
        if target not in range(1, 10000):
            return -1
        if not nums:
            return -1
        left = 0
        right = len(nums) - 1
        while left < right:
            middle = left + ((right - left) >> 1)
            if nums[middle] == target:
                return middle
            elif nums[middle] > target:
                right = middle
            else:
                left = middle + 1
        else:
            return -1

if __name__ == '__main__':
    s = Solution()
    res = s.search(nums=[-1, 0, 3, 5, 9, 12, 37], target=12)
    print(res)

三、其他解法与类似

类似题目:

  • 力扣34,35,69,367