二分查找红蓝染色法
二分查找算法是一种在有序数组中查找特定元素的高效算法。它通过将目标值与数组中间的元素进行比较,根据比较结果决定是继续在数组的左半部分还是右半部分进行查找,从而逐步缩小搜索范围,直到找到目标值或搜索范围为空。
二分查找算法的步骤:
-
确定搜索范围:开始时,搜索范围是整个数组。
-
找到中间元素:计算数组中间位置的索引,通常为
low + (high - low) // 2。 -
比较中间元素与目标值:
- 如果中间元素正好是目标值,搜索结束,返回中间元素的索引。
- 如果目标值小于中间元素,那么在数组的左半部分继续搜索。
- 如果目标值大于中间元素,那么在数组的右半部分继续搜索。
-
更新搜索范围:根据上一步的比较结果,更新搜索的起始点
low和结束点high。 -
重复步骤2-4,直到找到目标值或
low大于high(即搜索范围为空)。
- 34.在排序数组中查找元素的第一个和最后一个位置 leetcode.cn/problems/fi…
闭区间 给出一串有序数字,找到大于等于的给定值的数字 暴力解法是一次次对比,时间复杂度O(n)
但是忽略了数组有序
先减后加防止溢出
要注意每时每刻都需要是闭区间
def lower_bound(nums: List[int], target: int) -> int:
left = 0
right = len(nums) - 1 # 闭区间[left, right]
while left <= right: # 区间不为空
mid = (left + right) // 2
if nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return left
开区间
左闭右开区间
def lower_bound2(nums: List[int], target: int) -> int:
left = 0
right = len(nums) # 左闭右开区间[left, right)
while left < right:
mid = (left + right) // 2
if nums[mid] < target:
left = mid + 1 # [mid + 1, right)
else:
right = mid # [left, mid)
return left # right
全部开区间
def lower_bound3(nums: List[int], target: int) -> int:
left = -1
right = len(nums) # 开区间(left, right)
while left + 1 < right:
mid = (left + right) // 2
if nums[mid] < target:
left = mid # (mid, right)
else:
right = mid # (left, mid)
return right
如果不是大于等于 大于 可以视作为大于等于 小于 看成是大于等于x左边那个数字 (>=x) - 1 小于等于 看成是大于x的左边那个数字 (>x) - 1
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
start = lower_bound(nums, target)
if start == len(nums) or nums[start] != target:
return [-1, -1]
end = lower_bound(nums, target + 1) - 1
return [start, end]
课后题解:
- 35.搜索插入位置 leetcode.cn/problems/se…
- 704.二分查找 leetcode.cn/problems/bi…
- 275.H 指数 II leetcode.cn/problems/h-…
二分查找搜索旋转排序数组
- 162.寻找峰值 leetcode.cn/problems/fi…
- 153.寻找旋转排序数组中的最小值 leetcode.cn/problems/fi…
- 33.搜索旋转排序数组 leetcode.cn/problems/se…
课后作业:
- 154.寻找旋转排序数组中的最小值 II leetcode.cn/problems/fi…