目录:
目的
[-1,0,3,4,6,10,13,14], 13查找后的结果是6,13 出现在nums中并且下标为 6。
思路
这个任务是实现无重复数字的升序数组的二分查找。你在超市的货架上找一种特别的商品,它的价格是 100元(目标值)。超市的货架上,所有商品都按价格从低到高排列(有序数组)。你急着买东西,不想从头到尾一个一个看,而是选择一种高效的方法——二分查找。
开始寻找:
- 货架左边的商品(最便宜的)就是 left=0,右边的商品(最贵的)就是 right=len(nums) - 1。
- 你站在货架中间,准备通过分段缩小范围来找目标价格
mid
= left + (right - left) // 2。
三种可能性:你站在 mid
商品位置后判断
- 如果价格刚好是目标:
- 你看了中间的商品价格,刚好是 100元!你兴奋地喊:“找到了!”。然后你记下这个商品的编号(返回
mid
),准备去买。- 如果中间价格太低:
- 中间商品的价格比 100元 低,比如 50元。你心想:“目标商品一定在更贵的右边部分。”
- 于是你走到右边,把
left
调整为mid + 1
,抛弃掉左半部分。如果中间价格太高:
- 中间商品的价格比 100元 高,比如 150元。你心想:“目标商品一定在更便宜的左边部分。”
- 于是你走到左边,把
right
调整为mid - 1
,抛弃掉右半部分。
查找结果:如果货架上的所有商品都检查完(left > right
),但还是没找到 100元 的商品,你无奈地摇摇头:“这个超市没有我要的东西。” 返回 -1
。
复杂度
-
时间复杂度:O(log n)
- 因为每次查找都将查找范围缩小一半。
-
空间复杂度:O(1)
- 只使用了常数级别的额外空间。
记忆秘诀
中间取一分:每次查找从数组的中间位置
mid
开始,分成左右两部分。左右范围缩:判断目标值和中间值的关系,选择一半继续搜索:
- 小了,看左边(
right = mid - 1
)。- 大了,看右边(
left = mid + 1
)。等值快返回:如果中间值刚好等于目标值,立即返回结果,查找结束。
不等再分拨:如果目标值不在中间,再缩小范围,继续重复步骤。
python代码
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param nums int整型一维数组
# @param target int整型
# @return int整型
#
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2 # 避免直接使用(left + right) // 2 可能造成的溢出
if nums[mid] == target:
return mid # 找到目标值,返回下标
elif nums[mid] < target:
left = mid + 1 # 目标值在右侧
else:
right = mid - 1 # 目标值在左侧
return -1 # 未找到目标值
* 欢迎大家探讨新思路,能够更好的理解和记忆