经典 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]

Hot100:Search Insert Position 排序数组中目标值插入位置的二分查找实战(LeetCode 35)

副标题 / 摘要 Search Insert Position 是二分查找的「Hello World」级题目:返回目标值在有序数组中的插入位置(存在返回下标,不存在返回应插入的下标)。本文用统一的 lower_bound 模板,把这个问题讲清楚,并展示其在日志、配置和策略表中的工程应用。 预计阅读时长:8~10 分钟 适用场景标签:二分查找入门、插入位置、范围查找 SEO 关键词:search insert position, lower_bound, 二分插入, 排序数组插入位置, LeetCode 35, Hot100 目标读者与背景 目标读者 知道二分查找基本原理,但还没形成自己的模板的同学; 在工程中经常对有序列表做插入 / 查找操作的后端 / 前端开发者; 刚开始刷 LeetCode,想用一道题把「下界二分」吃透的人。 为什么这题重要? 它是 most basic 的「lower_bound」模型: 第一个大于等于目标值的下标。 理解它之后: 起始位置 / 插入位置 / 统计 ≤ / ≥ 某值数量等,都可以统一用同一个模板。 在工程中: 策略阈值表、时间戳列表、版本列表等,都会用到类似逻辑。 A — Algorithm(题目与算法) 题目重述 给定一个按非降序排序的整数数组 nums 和一个目标值 target。 请在数组中搜索 target,如果存在则返回其下标; 如果不存在,则返回它按顺序插入时应该在的位置。 要求算法时间复杂度为 O(log n)。 输入 nums: 已排序(非降序)的整数数组,长度为 n target: 目标整数 输出 ...

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

Hot100:在排序数组中查找元素的起始和结束位置,一套二分模板搞定 Search Range(LeetCode 34)

副标题 / 摘要 很多同学会写“找一个等于目标的二分”,但一到“找目标的起始和结束位置”就容易被边界条件卡住。本文用统一的下界 / 上界二分模板,彻底吃透 Search Range 类型问题,并给出多语言实现和工程场景示例。 预计阅读时长:10~15 分钟 适用场景标签:二分查找、日志区间查询、时间序列检索 SEO 关键词:search range, first and last position, 二分查找边界, lower_bound, upper_bound, LeetCode 34, Hot100 目标读者与背景 目标读者 已经知道二分查找基本写法,但一到“找起始位置/结束位置”就容易出错的同学; 经常对日志、监控指标做时间区间检索的工程师; 准备面试时希望掌握一套可复用二分模板的开发者。 背景 / 动机 几乎所有互联网系统里都有“按时间排序的日志 / 事件 / 指标”: 比如按时间排序的访问日志; 按上报时间排序的监控数据点; 按 ID 排序的业务记录。 在这些有序数据上,最常见的操作之一就是: 找出“所有值等于 X 的记录”的区间 [start, end]。 这道 LeetCode 经典题「Search for a Range」正是这个需求的抽象版本。 A — Algorithm(题目与算法) 题目重述 给定一个按非降序排序的整数数组 nums 和一个目标值 target。 请在数组中找到目标值的起始位置和结束位置,以数组 [start, end] 形式返回。 如果数组中不存在目标值,返回 [-1, -1]。 要求时间复杂度为 O(log n)。 ...

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

咒语与药水的成功组合:排序 + 二分查找秒杀乘积约束问题(LeetCode 2300)

副标题 / 摘要 一道典型的“乘积 ≥ 阈值”计数题,看起来像是 O(n²) 的双重循环,实际上用「排序 + 二分查找」就能把复杂度压到 O((n+m)log m)。本文从题意抽象、核心公式到多语言实现,带你把这类阈值匹配问题彻底吃透。 预计阅读时长:10~15 分钟 适用场景标签:二分查找、排序计数、阈值匹配 SEO 关键词:spells and potions, successful pairs, 二分查找, lower_bound, 乘积约束 目标读者与背景 目标读者 已熟悉基本二分查找,想提升「在有序数组上做计数」能力的同学 后端 / 算法工程师,经常处理阈值判断与配对统计的问题 准备技术面试,希望积累“排序 + 二分”模板的开发者 为什么这题值得单独写一篇? 它把一个表面 O(n²) 的「所有配对」问题,转化成了对有序数组的二分计数; 公式非常典型:把 a * b ≥ success 转成 b ≥ ceil(success / a); 这种思路在推荐系统、风控额度、资源匹配等业务里屡见不鲜。 A — Algorithm(题目与算法) 题目重述 给定两个整数数组 spells 和 potions,以及一个正整数 success。 对于每个咒语 spells[i],我们定义它与药水 potions[j] 的组合是“成功”的,当且仅当: spells[i] * potions[j] >= success 请返回一个数组 ans,其中 ans[i] 表示第 i 个咒语可以与多少个药水形成成功组合。 ...

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

固定长度子数组 + 至少 m 个不同元素:几乎唯一子数组的最大和(LeetCode 2841)

副标题 / 摘要 一道看似麻烦的子数组题:长度必须固定为 k,元素种类又要至少 m 个,还要在满足约束下让子数组和最大。本文通过「固定窗口滑动 + 计数哈希表」,构造 O(n) 级别的简洁算法,并给出多语言实现与工程实践案例。 预计阅读时长:12~15 分钟 适用场景标签:滑动窗口进阶、distinct 计数、子数组最大和 SEO 关键词:almost unique subarray, at least m distinct, sliding window, subarray max sum 目标读者与背景 目标读者 已经掌握基础滑动窗口(如「最长无重复子串」)的刷题同学 后端 / 数据分析工程师,需要在数组或数据流上做实时统计 准备中高级面试,希望写出更工程化解法的开发者 问题背景 / 动机 许多业务都有类似需求: 推荐系统:固定长度的推荐位里,既要保证足够多的不同品类,又希望整体评分尽量高; 监控系统:在最近的固定时间窗口里,要求至少有 m 个不同指标处于活跃状态; 行为分析:在 k 次连续行为中,至少访问 m 个不同页面,且总价值最大。 本题正是这类需求的抽象版,非常适合用来练习滑动窗口 + 计数哈希表的组合技。 A — Algorithm(题目与算法) 题目重述 给定整数数组 nums,正整数 m 和 k。 如果一个长度为 k 的子数组中至少包含 m 个不同的元素,则称其为“几乎唯一子数组(almost unique subarray)”。 请在所有几乎唯一子数组中,找到元素和的最大值;如果不存在这样的子数组,则返回 0。 输入 ...

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

最少涂色次数拿到 k 个连续黑块:滑动窗口的极简解法(LeetCode 2379)

副标题 / 摘要 一道看似暴力 O(n·k) 的刷题小题,实际只需要一个固定长度滑动窗口就能在 O(n) 内秒杀。本文从题意还原、窗口建模,到多语言实现与工程场景,把这类「固定长度窗口 + 计数」问题一网打尽。 预计阅读时长:8~10 分钟 适用场景标签:滑动窗口、字符串处理、面试刷题 SEO 关键词:LeetCode 2379, minimum recolors, sliding window, k consecutive black blocks 目标读者与背景 目标读者 正在系统刷 LeetCode / 力扣、想提升滑动窗口题目通过率的开发者 面试中经常被「固定窗口 + 计数」卡住的同学 想把算法题思路迁移到业务代码中的后端 / 前端工程师 为什么这个问题值得认真写一篇? 它是滑动窗口最基础的形态:窗口长度固定,维护一个简单计数。 很多更难的题(如「最长连续 1」、「至少 k 个元素」等)都可以退化到这个模板。 工程里也经常遇到类似需求:连续 k 个时间片、连续 k 条日志、连续 k 个卡片槽位是否满足某种条件。 A — Algorithm(题目与算法) 题目描述(用自己的话再说一遍) 给你一个只包含 'W'(白块)和 'B'(黑块)的字符串 blocks,还有一个整数 k。 你可以进行若干次操作,每次操作: 选择一个位置,如果那里是 'W',就可以把它涂成 'B'。 目标是: 通过涂色,让字符串中出现至少一次长度为 k 的连续黑色块(k 个连续 'B'),并且总操作次数最少。问最少要涂几次? 输入 blocks: str,只包含字符 'W' 和 'B' k: int,目标连续黑块长度,1 ≤ k ≤ len(blocks) 输出 ...

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