基础算法之二分查找 | 豆包MarsCode AI刷题

128 阅读2分钟

二分查找红蓝染色法

二分查找算法是一种在有序数组中查找特定元素的高效算法。它通过将目标值与数组中间的元素进行比较,根据比较结果决定是继续在数组的左半部分还是右半部分进行查找,从而逐步缩小搜索范围,直到找到目标值或搜索范围为空。

二分查找算法的步骤:

  1. 确定搜索范围:开始时,搜索范围是整个数组。

  2. 找到中间元素:计算数组中间位置的索引,通常为 low + (high - low) // 2

  3. 比较中间元素与目标值

    • 如果中间元素正好是目标值,搜索结束,返回中间元素的索引。
    • 如果目标值小于中间元素,那么在数组的左半部分继续搜索。
    • 如果目标值大于中间元素,那么在数组的右半部分继续搜索。
  4. 更新搜索范围:根据上一步的比较结果,更新搜索的起始点 low 和结束点 high

  5. 重复步骤2-4,直到找到目标值或 low 大于 high(即搜索范围为空)。

闭区间 给出一串有序数字,找到大于等于的给定值的数字 暴力解法是一次次对比,时间复杂度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]

课后题解:

二分查找搜索旋转排序数组

课后作业: