力扣刷题TOP101:15.BM17 二分查找-II

目录:

目的

思路

复杂度

记忆秘诀

python代码

目的

[-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  # 未找到目标值

* 欢迎大家探讨新思路,能够更好的理解和记忆

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乱七八糟2333

随缘打赏,一分也是爱!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值