二分查找篇——搜索旋转排序数组【LeetCode】一次二分查找

33. 搜索旋转排序数组


一、算法逻辑(逐步通顺讲解每一步思路)

本题的输入是一个被旋转的升序数组 nums(无重复元素),我们要返回目标值 target 的下标,不存在则返回 -1

这段代码的思路属于"自适应二分查找 ":不显式地找出旋转点,而是通过构造判断逻辑 check(i),直接决定二分时该舍弃哪一侧。

✅ 1️⃣ 核心函数 check(i):判断 nums[i] 是否"足够大"

函数逻辑分两种情况讨论当前值 nums[i] 相对于旋转点的位置(通过 nums[-1] 即最后一位判断):

python 复制代码
if x > nums[-1]:
    # 说明 x 在第一段(旋转点左边),我们只保留:
    # 情况 1:target 也在第一段,并且 x >= target
    return target > nums[-1] and x >= target
else:
    # x 在第二段,我们只保留:
    # 情况 2:target 在第一段(目标比最后一个值大)
    # 情况 3:target 在第二段,并且 x >= target
    return target > nums[-1] or x >= target

该判断本质上模拟了对两个段的划分,并控制搜索落在目标段内的区间中。

✅ 2️⃣ 二分搜索框架(偏左写法)

python 复制代码
left = -1
right = len(nums) - 1
  • 二分搜索区间为开区间 (left, right]

  • 循环条件为 left + 1 < right

  • 每轮检查 mid = (left + right) // 2 是否满足 check(mid)

    • 若满足,收缩右边界 right = mid

    • 否则丢弃左半边,更新 left = mid

✅ 3️⃣ 返回结果

循环结束后,right 是最有可能的候选位置,再判断是否真的匹配:

python 复制代码
return right if nums[right] == target else -1

二、核心点总结

✅ 本算法的关键亮点是:

  • 利用 nums[-1] 作为旋转点分界参考,将数组划分为两段;

  • 构造统一判断函数 check(i),将"是否保留右边界"问题变成布尔表达式;

  • 避免显式找出旋转点,实现了逻辑一体化的高效搜索

  • 使用 (left, right] 开区间 + 偏左二分模板,使边界处理清晰准确。

✅ 可视为「旋转数组查找 + lower_bound」的融合模板。

python 复制代码
class Solution:
    def search(self, nums: List[int], target: int) -> int:
        def check(i: int) -> bool:
            x = nums[i]
            if x > nums[-1]:
                return target > nums[-1] and x >= target
            return target > nums[-1] or x >= target

        left, right = -1, len(nums) - 1  # 开区间 (-1, n-1)
        while left + 1 < right:  # 开区间不为空
            mid = (left + right) // 2
            if check(mid):
                right = mid
            else:
                left = mid
        return right if nums[right] == target else -1

三、时间复杂度分析

每轮搜索都将区间折半,总轮数为 O(log n)

✅ 时间复杂度为:O(log n)


四、空间复杂度分析

只使用了常数级别变量,无递归、无额外数组:

✅ 空间复杂度为:O(1)


✅ 总结一句话

本算法通过构造灵活的 check() 函数,避免显式分段判断,将旋转数组的复杂性"封装"为条件函数内部的逻辑判断 ,结合偏左二分,实现了 时间复杂度 O(log n)、空间复杂度 O(1) 的简洁高效搜索方案,是 LeetCode 33 题的极优解法之一。

相关推荐
达子66618 小时前
Git中文文件名乱码显示SHA-1 哈希值
git·算法·哈希算法
VkN2X2X4b18 小时前
算法性能测试的统计建模与误差估计的技术9
算法
曲幽18 小时前
FastAPI自动生成的API文档太丑?我花了一晚上把它改成了客户愿意付费的样子
python·fastapi·web·swagger·openapi·scalar·docs
程序设计实验室18 小时前
后 Django 时代:SQLAlchemy 2.0、Tortoise 与 Piccolo 三大异步 ORM 选型指南
python
Allen_LVyingbo18 小时前
量子计算Dirac Notation基本教学—从零基础到读懂量子信息论文(上)
开发语言·数据结构·架构·健康医疗·量子计算
爱分享的阿Q18 小时前
技术饱和度视角下的编程语言选择:一场关于供需博弈的深度思考
java·python·go
笨笨饿18 小时前
28_关于交叉学科的学习方法
linux·服务器·c语言·算法·学习方法·机械
E_ICEBLUE18 小时前
Python 办公自动化:快速将 HTML 转换为 PDF 格式
python·pdf·html
历程里程碑18 小时前
Protobuf vs JSON vs XML:小白该怎么选?
xml·大数据·数据结构·elasticsearch·链表·搜索引擎·json
Highcharts.js18 小时前
企业级可视化生态系统|关于Highcharts集成的前端框架、后端编程语言与生态
开发语言·javascript·python·前端框架·编辑器·编程语言·highcharts