AIUnlimited
🌳

AI基础

🌱
AI 种子

从零开始

🌿
AI 萌芽

打好基础

🌳
AI 枝干

付诸实践

🏕️
AI 树冠

深入探索

🌲
AI 森林

精通AI

🔨

AI精通

✏️
AI 草图

从零开始

🪨
AI 雕刻

打好基础

⚒️
AI 匠心

付诸实践

💎
AI 打磨

深入探索

🏆
AI 杰作

精通AI

📘

AI实战

📖
理解开源模型

开源模型的基础知识和资源

🎯
问题到模型任务

将业务问题转化为模型任务

⚡
跑通第一个模型

30分钟快速看到第一个结果

🔧
微调与评测

微调模型并评估性能

🚀
应用系统

构建实际AI应用系统

🎨
生成式AI

探索AIGC的开源模型

🤖
Agent智能体

学习Agent框架和MCP工具

📐
基础补充

LLM基础知识和评测

🎓

Claude 学院

🤖
Claude 101 入门

用 Claude 学习 AI 基础知识

💻
Claude Code 101 入门

让 Claude 成为你的结对编程伙伴

🤝
Claude Cowork 入门

与 Claude 协作完成复杂项目

⚙️
Claude 平台 101

使用 Claude API 构建应用

实验室

已加载 7 个实验
🧬神经网络沙盒🤖AI 还是人类?🥋提示工程道场🏁算法竞速🧠AI 知识挑战🏗️系统设计画布
🎯模拟面试进入实验室→
🚀

职业发展

🚀
面试发射台

开启你的旅程

🌟
行为面试精通

掌握软技能

💻
技术面试

通过编程轮次

🤖
AI与ML面试

ML面试精通

🏆
Offer与未来

拿下最好的Offer

立即开始
AIUnlimited

AI 教育平台

沪ICP备18025655号-11

学习

  • AI基础
  • AI实战
  • Claude学院
  • 实验室
  • 职业发展

社区

  • 关于
  • 常见问题

支持

  • 服务条款
  • 隐私政策
  • 联系我们
AI & 工程学习计划›✏️ AI 草图›课程›二分搜索模式
🔍
AI 草图 • 中级⏱️ 17 分钟阅读

二分搜索模式

经典二分搜索 - 快速回顾

二分搜索每一步将搜索空间减半。在 n 个元素的排序数组上,它在 O(log n) 时间内找到目标。

def binary_search(nums, target):
    lo, hi = 0, len(nums) - 1
    while lo <= hi:
        mid = (lo + hi) // 2
        if nums[mid] == target:
            return mid
        elif nums[mid] < target:
            lo = mid + 1
        else:
            hi = mid - 1
    return -1

简单 - 但二分搜索的真正威力远远超出了排序数组。

搜索空间概念

只要您在某个范围内有单调条件,二分搜索就会起作用。 “数组”甚至不需要存在 - 你只需要一个范围 [lo, hi] 和一个在某个边界从 False 翻转到 True (反之亦然)的函数。

Search space:  [lo .................. hi]
Condition:      F  F  F  F  T  T  T  T
                          ^-- answer
🤯

二分搜索首次发布于 1946 年,但第一个无错误版本直到 1962 年才编写 - 16 年的差一错误!

对答案进行二分查找

不要搜索数组,而是搜索答案空间。问:“我能达到结果 X 吗?”如果是,请尝试较小的;如果没有,请尝试更大的。

示例:Koko 吃香蕉

Koko 有 n 堆香蕉和 h 小时。找到最小进食速度,以便她及时吃完。

def min_speed(piles, h):
    lo, hi = 1, max(piles)
    while lo < hi:
        mid = (lo + hi) // 2
        hours = sum((p + mid - 1) // mid for p in piles)
        if hours <= h:
            hi = mid      # speed works, try slower
        else:
            lo = mid + 1  # too slow, go faster
    return lo

答案空间是 [1, max(piles)] 并且条件是单调的 - 更高的速度总是意味着更少的时间。

二分搜索缩小了最小进食速度的答案空间
对答案进行二分搜索:缩小每次迭代的可行速度范围。

旋转排序数组

已排序的数组在某个枢轴处旋转:[4, 5, 6, 7, 0, 1, 2]。一半总是排序的。比较 mid 和 lo 来决定哪一半,然后检查目标是否属于已排序的一半。

[4, 5, 6, 7, 0, 1, 2]
 L        M        R
Left half [4..7] is sorted.
Target 1 not in [4..7] → search right.
第 7 课,共 10 课已完成 0%
←堆与优先队列

讨论

登录 参与讨论

🧠小测验

在旋转排序数组 [3,4,5,1,2] 中,当 mid=2(值 5)时哪一半已排序?

第一次和最后一次出现

要找到第一个出现,当您击中目标时,不要停止 - 设置 hi = mid 并继续向左搜索。对于最后,设置 lo = mid + 1 并向右搜索。

这对搜索还为您提供了目标的计数:last - first + 1。

峰值元素

比两个邻居都大的元素。即使在未排序的数组中,二分搜索也有效:如果 nums[mid] < nums[mid + 1],则峰值在右侧;如果 nums[mid] < nums[mid + 1],则峰值在右侧;否则它在左边。 O(log n)。

🤔
Think about it:

为什么即使数组未排序,峰值查找仍可与二分搜索一起使用?什么属性取代了这里的排序顺序?

在二维矩阵中搜索

如果行已排序并且每行的第一个元素大于前一行的最后一个,则将矩阵视为 m × n 元素的单个排序数组。将索引 k 映射到行 k // n、列 k % n。

没有库的平方根

找到最大的整数 x 其中 x * x ≤ n。搜索空间:[0, n]。经典的二分搜索答案。

def sqrt(n):
    lo, hi = 0, n
    while lo <= hi:
        mid = (lo + hi) // 2
        if mid * mid <= n:
            lo = mid + 1
        else:
            hi = mid - 1
    return hi

“最小化最大”模式

诸如“拆分数组最大总和”或“D 天内运送包裹的能力”之类的问题要求您最小化最坏的情况。答案是单调的:如果容量 C 有效,那么 C+1 也有效。对 C 进行二分查找

🧠小测验

对于”D 天内运送包裹的能力”,二分搜索的搜索空间是多少?

通用模板

lo, hi = min_possible, max_possible
while lo < hi:
    mid = (lo + hi) // 2
    if condition(mid):
        hi = mid        # mid works, try smaller
    else:
        lo = mid + 1    # mid fails, need larger
return lo

根据您是否寻求第一个 True 或 最后一个 True 来调整 hi = mid 与 lo = mid。

🧠小测验

在大小为 S 的答案空间上进行 O(n) 可行性检查的二分搜索的时间复杂度是多少?

🤔
Think about it:

当您在问题陈述中看到短语“最小可能的最大值”或“最大可能的最小值”时,您应该立即想到什么?


📚 进一步阅读

  • NeetCode - 二分搜索播放列表 - 从易到难的精选问题
  • 技术面试手册 - 二分搜索 - 模式、技巧和陷阱
  • 【LeetCode 二分查找学习计划](https://leetcode.com/studyplan/binary-search/)-递进题集