二分搜索(常规、左边界、右边界)

1.  概述

  二分查找的思想是在有序数组里根据中间值来收缩搜索空间。时间复杂度为O(log(n))。

2. Code实现

2.1 常规

 1 # 数组查找是否某个数,存在返回其下标,
 2     def binarySearch_any(self, nums, target):
 3         if not nums or len(nums) == 0:
 4             return -1
 5         n = len(nums)
 6         # 左右均是闭区间
 7         left, right = 0, n - 1
 8         # <=: 闭区间[left, right]内查找
 9         # 若一直未找到,left = right + 1,写成区间:[right + 1, right]
10         while left <= right:
11             # 方式left + right太大越界
12             mid = left + (right - left) // 2
13             # 找到
14             if nums[mid] == target:
15                 # *** 1. 直接返回 ***
16                 return mid
17             elif nums[mid] < target:
18                 # 注意
19                 left = mid + 1
20             elif nums[mid] > target:
21                 # 注意
22                 right = mid - 1
23         # 未找到
24         # *** 2. 直接返回 ***
25         return left

2.2 左边界

# 返回排序数组中第一次出现的下标,记找左边界
    def binarySearch_left(self, nums, target):
        if not nums or len(nums) == 0:
            return -1
        n = len(nums)
        # 左右均是闭区间
        left, right = 0, n - 1
        # <=: 闭区间[left, right]内查找
        while left <= right:
            mid = left + (right - left) // 2
            if nums[mid] == target:
                # *** 1. 别返回,收缩右边界,锁定左边界 ***
                right = mid - 1
            elif nums[mid] < target:
                # 搜索区间变为[mid, right]
                left = mid + 1
            elif nums[mid] > target:
                # 搜索区间变为[left, mid - 1]
                right = mid - 1
        # *** 2. 最后要检查left越界情况 ***
        if left >= n or nums[left] != target:
            return -1
        return left

2.3 右边界

# 返回排序数组中最后一次出现的下标,记找右边界
    def binarySearch_right(self, nums, target):
        if not nums or len(nums) == 0:
            return -1
        n = len(nums)
        # 左右均是闭区间
        left, right = 0, n - 1
        while left <= right:
            mid = left + (right - left) // 2
            if nums[mid] == target:
                # *** 1. 别返回,收缩左边界,锁定右边界 ***
                left = mid + 1
            elif nums[mid] < target:
                # 搜索区间变为[mid + 1, right]
                left = mid + 1
            elif nums[mid] > target:
                # 搜索区间变为[left, mid - 1]
                right = mid - 1
        # *** 2. 最后要检查right越界情况 ***
        if right < 0 or nums[right] != target:
            return -1
        return right

3. 结语

  努力去爱周围的每一个人,付出,不一定有收获,但是不付出就一定没有收获! 给街头卖艺的人零钱,不和深夜还在摆摊的小贩讨价还价。愿我的博客对你有所帮助(*^▽^*)(*^▽^*)!

  如果客官喜欢小生的园子,记得关注小生哟,小生会持续更新(#^.^#)(#^.^#)。

posted @ 2021-08-16 18:36  抚琴尘世客  阅读(574)  评论(0编辑  收藏  举报