二分查找区间怎么选:从候选集合到边界更新

写二分查找时,我们经常先看到这样的初始化: left = 0 right = len(nums) - 1 本文讨论的输入是按非递减顺序排列、允许重复值的 list[int]。精确查找要返回某个等于 target 的实际下标,不存在时返回 -1;左边界查找要返回 [0, n] 中第一个满足 nums[i] >= target 的位置,如果不存在这样的数组元素,就返回 n。 它看起来像是在声明一个闭区间,但只看这两行还不够。真正决定区间含义的是下面四件事是否一致: left 和 right 是候选下标、未分类边界,还是哨兵; 循环在什么条件下说明仍有实际元素需要检查; 检查 mid 后,更新是否正确排除了它; 循环结束时,哪个位置承载最终答案。 最可靠的判断方法不是背代码,而是先问一句: 当前哪些实际下标还没有被排除或分类,答案位置又被限制在哪个范围内? 这些持续成立的事实就是二分查找的循环不变式。区间符号、初始化和更新规则都应该从它推出来。 闭区间 [left, right] 当 left 和 right 都指向尚未排除的实际数组下标时,候选集合是闭区间: left = 0 right = len(nums) - 1 此时两个端点都可能是答案,所以只要 left <= right,区间就仍然非空: while left <= right: 如果 mid 不是答案,下一轮必须把它排除: if nums[mid] < target: left = mid + 1 else: right = mid - 1 因此,这套约定是: 项目 规则 候选集合 [left, right] 初始化 left = 0, right = n - 1 非空条件 left <= right 排除 mid left = mid + 1 或 right = mid - 1 空区间 left > right 它很适合“找到任意一个等于 target 的位置”:命中时直接返回,区间为空时返回不存在。 ...

2026年8月14日 · 4 分钟 · map[name:Jeanphilo]

LeetCode 74:搜索二维矩阵

给你一个 m x n 的整数矩阵 matrix 和一个整数 target。如果 target 在矩阵中,返回 True;否则返回 False。 题目给出的矩阵满足两个条件: 每一行都按非递减顺序排列。 每一行的第一个整数都严格大于上一行的最后一个整数。 要求算法的时间复杂度为 O(log(m * n))。 例如,对于下面的矩阵: 1 3 5 7 10 11 16 20 23 30 34 60 target = 3 时返回 True。 target = 13 时返回 False。 约束如下: 1 <= m, n <= 100 -10^4 <= matrix[i][j], target <= 10^4 LeetCode 提供的方法签名是: class Solution: def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: pass 第一步:扫描每一个元素 现在只有题目条件和方法签名,还没有一段能判断目标值是否存在的代码。先解决最基本的问题:怎样得到一个可以直接运行、结果确定正确的版本? 当前基线无法对示例中的 3 或 13 给出答案。加入一层遍历每一行的循环,再在当前行中检查每一个值。遇到目标值就立即返回 True;只有检查完所有元素仍未命中时,才返回 False。 ...

2026年8月13日 · 6 分钟 · map[name:Jeanphilo]

最大正负数计数:用二分在排序数组中统计正整数和负整数数量的最大值(LeetCode 2529)

副标题 / 摘要 给定一个有序整数数组,如何在 O(log n) 时间内分别统计负数和正数的个数,并返回两者中的较大值?这道「Maximum Count of Positive & Negative Integers」正是边界型二分的练习题。本文用上下界二分一次性搞定负数结束和正数起点。 预计阅读时长:8~10 分钟 适用场景标签:二分查找、边界计数、排序数组 SEO 关键词:maximum count, positive negative, 二分统计, 上下界, 有序数组计数 目标读者与背景 目标读者 已经会写 basic binary search,希望进阶到“计数型二分”的同学; 在工程中有基于排序数据做区间计数需求的工程师; 准备面试,想把二分查找的上下界技巧练熟的开发者。 背景 / 动机 在各种日志 / 指标 / 数据分析场景中,我们经常会对有序数据做计数: 比如统计小于 0 的条目数量; 统计大于某个阈值的条目数量; 找到“负数段结束”和“正数段开始”的位置。 这道 LeetCode 题「Maximum Count of Positive & Negative Integers」是这类需求的简化模型,非常适合作为上下界二分的练习。 A — Algorithm(题目与算法) 题目重述 给定一个按非降序排序的整数数组 nums。 数组中可能包含负数、0 和正数。 定义: countNeg = 数组中小于 0 的元素数量; countPos = 数组中大于 0 的元素数量。 请返回 max(countNeg, countPos)。 输入 ...

2025年12月4日 · 8 分钟 · map[name:Jeanphilo]

比目标字母大的最小字母:有序字符数组上的二分查找技巧(LeetCode 744)

副标题 / 摘要 这道题看似只是“找一个比目标大的字母”,本质上是经典的上界二分(upper_bound)问题:在有序字符数组中找到第一个 > target 的元素,并在找不到时从头环绕。本文给出完整的二分模板和多语言实现,帮你稳拿这类边界题。 预计阅读时长:8~10 分钟 适用场景标签:二分查找进阶、字符数组、上界查找 SEO 关键词:find smallest letter greater than target, upper_bound, 二分查找字符数组 目标读者与背景 目标读者 已经掌握基本二分查找,想进一步熟悉上下界(upper/lower bound)的同学; 在工程中需要在有序集合中找到“下一个更大值”的开发者; 准备中高级面试,想通过一道题统一上界二分写法的工程师。 背景 / 动机 很多系统都会用到“环形有序列表”的概念: 比如按字母排序的标签、按时间排序的分片; 想要找“比当前值更大的下一个值”,找不到就从头开始。 这道题「Find Smallest Letter Greater Than Target」正是这种模式的简化版,是练习上界二分的好题。 A — Algorithm(题目与算法) 题目重述 给定一个按非降序排序的字符数组 letters,数组中的字母都是小写英文字母。 给定一个字符 target,请你找到数组中严格大于 target 的最小字母并返回。 注意:letters 数组是环绕的——如果不存在这样的字母,则返回数组的第一个元素。 输入 letters: 排序好的小写字母数组,长度为 n,且 letters 中至少有两个不同的字母; target: 一个小写字母。 输出 字符:数组中比 target 大的最小字母;若不存在,则为 letters[0]。 示例 1 letters = ['c', 'f', 'j'] target = 'a' 所有比 'a' 大的字母有 ['c', 'f', 'j']; 其中最小的是 'c'。 输出:'c' ...

2025年12月4日 · 6 分钟 · map[name:Jeanphilo]

经典 Binary Search:在排序数组中查找目标值索引的统一模板(LeetCode 704)

副标题 / 摘要 二分查找是所有算法面试和工程系统中的“必修课”。本文以最基础的「在有序数组中查找目标值」为例,从题意、边界到统一模板,系统整理 Binary Search 的写法,并配套多语言实现,帮助你彻底告别二分边界恐惧症。 预计阅读时长:8~10 分钟 适用场景标签:二分查找基础、数组检索、性能优化 SEO 关键词:binary search, LeetCode 704, 二分查找模板, 有序数组目标索引 目标读者与背景 目标读者 刚开始系统刷题、希望夯实基础二分查找的同学; 在工程中经常需要在有序列表中查找、定位数据的后端 / 前端工程师; 曾经被二分查找的边界条件困扰、希望形成统一模板的开发者。 为什么这题值得认真学? 它是 LeetCode 704:Binary Search,二分查找的最基础版本; 几乎所有高级二分题(Search Range、插入位置、求上下界)都以此为内核; 大量工程场景(有序列表查找、策略表、时间线等)都可以套用这个模板。 A — Algorithm(题目与算法) 题目重述 给定一个按非降序排序的整数数组 nums 和一个整数 target。 请你在数组中查找 target,如果存在,则返回其下标;否则,返回 -1。 要求算法的时间复杂度为 O(log n)。 输入 nums: 已排序(非降序)的整数数组,长度为 n target: 要查找的整数 输出 若 target 存在于 nums 中,则返回其下标; 否则返回 -1。 示例 1 nums = [-1, 0, 3, 5, 9, 12] target = 9 数组中存在 9,且在下标 4: ...

2025年12月4日 · 6 分钟 · map[name:Jeanphilo]