image.pngimage.pngimage.png

零、⼆分查找框架

  1. def binarySearch(self, nums,target):
  2. left = 0
  3. right = ... # 注意
  4. while ...:
  5. mid = (left + (right - left)) // 2
  6. if nums[mid] > target:
  7. ...
  8. elif nums[mid] < target:
  9. ...
  10. elif nums[mid] == target:
  11. ...
  12. return ...

image.png

⼀、寻找⼀个数(基本的⼆分搜索)

image.png
image.pngimage.pngimage.pngimage.pngimage.pngimage.png

⼆、寻找左侧边界的⼆分搜索

image.pngimage.pngimage.pngimage.pngimage.pngimage.pngimage.pngimage.png
image.pngimage.png

三、寻找右侧边界的⼆分查找

image.pngimage.pngimage.pngimage.pngimage.pngimage.png

四、逻辑统⼀

image.pngimage.pngimage.pngimage.pngimage.pngimage.pngimage.png

练习题目

剑指 Offer 11. 旋转数组的最小数字

image.png
image.png
image.png

  1. class Solution:
  2. def minArray(self, numbers: [int]) -> int:
  3. i, j = 0, len(numbers) - 1
  4. while i < j:
  5. m = (i + j) // 2
  6. if numbers[m] > numbers[j]: i = m + 1
  7. elif numbers[m] < numbers[j]: j = m
  8. else: j -= 1
  9. return numbers[i]

实际上,当出现 nums[m] = nums[j]nums[m]=nums[j] 时,一定有区间 [i, m]内所有元素相等 或 区间 [m,j] 内所有元素相等(或两者皆满足)。对于寻找此类数组的最小值问题,可直接放弃二分查找,而使用线性查找替代。

  1. class Solution:
  2. def minArray(self, numbers: [int]) -> int:
  3. i, j = 0, len(numbers) - 1
  4. while i < j:
  5. m = (i + j) // 2
  6. if numbers[m] > numbers[j]: i = m + 1
  7. elif numbers[m] < numbers[j]: j = m
  8. else: return min(numbers[i:j])
  9. return numbers[i]