V

算法可视化

ZHEN
分享到微博分享到 XGitHub 仓库个人主页
学习工具算法复杂度速查算法学习路径
数据结构数组链表栈队列树堆哈希表图字典树并查集LRU 缓存跳表线段树B+ 树布隆过滤器树状数组
经典排序算法冒泡排序鸡尾酒排序双调排序选择排序插入排序二分插入排序希尔排序归并排序自顶向下归并快速排序三路快排双轴快排堆排序计数排序基数排序桶排序
图算法Dijkstra 最短路Kruskal 最小生成树Prim 最小生成树Bellman-Ford 最短路拓扑排序Floyd 多源最短路强连通分量2-SAT最大流二分图匹配LCA 倍增欧拉路径
动态规划编辑距离0-1 背包完全背包最长公共子序列最长递增子序列硬币找零方案数石子合并旅行商 TSP树形 DP数位 DP换根 DP
回溯与搜索N 皇后子集生成全排列组合总和迷宫寻路岛屿数量单词搜索数独A* 寻路
字符串KMP 字符串匹配Rabin-KarpBoyer-MooreManacher后缀数组LCP / height 数组AC 自动机Z 函数
数学与数论埃氏筛线性筛欧几里得算法快速幂扩展欧几里得中国剩余定理欧拉函数米勒-拉宾FFTPollard's Rho
计算几何凸包旋转卡壳最近点对线段相交扫描线求交
查找二分查找二分边界旋转数组搜索二分答案三分查找

三分查找(单峰极值)

查找 · 双探针对决 · 每轮丢掉 1/3

山顶在哪:二分为什么失灵

单峰数组先一路爬升、过峰后一路下降——像一座山。找峰顶时二分却失灵了:只看一个 a[mid],你根本不知道自己站在上坡还是下坡,没法决定往哪走。

两个探针,制造方向感

三分查找在区间里放两个三分点探针 m1、m2,让它们「对决」:若 a[m1] < a[m2],峰不可能在 m1 左侧(那边只会更矮)——丢掉左侧 1/3;否则丢右侧 1/3。每轮区间变 2/3,很快登顶。下面蓝/黄箭头就是两个探针(红/绿是区间端点),高亮的两根柱在对决,暗下去的是已排除区域——四轮登顶 12。右侧代码随每一步同步高亮。

1
4
7
9
12
10
6
3
2

单峰数组:一路爬升到峰顶再一路下降。二分在这儿失灵——只看 a[mid] 不知道自己在上坡还是下坡。三分的答案:放两个探针制造方向感

1function ternaryPeak(a: number[]): number {
2 let lo = 0, hi = a.length - 1; // 单峰数组
3 while (lo < hi) {
4 const third = ((hi - lo) / 3) | 0;
5 const m1 = lo + third, m2 = hi - third; // 两个三分探针
6 if (a[m1] < a[m2]) lo = m1 + 1; // 峰不在 m1 左侧:丢左 1/3
7 else hi = m2 - 1; // 峰不在 m2 右侧:丢右 1/3
8 }
9 return lo; // 峰顶
10}
11// 坡度二分变体:比较 a[mid] 与 a[mid+1],上坡去右、下坡去左
形状单峰(先升后降)
[lo, hi][0, 8]
m1 / m2— / —
候选数9
1 / 7

复杂度与同族变体

正确性:a[m1] < a[m2] ⟹ 峰在 (m1, hi](严格单峰下 m1 左侧必更矮)。
复杂度:每轮 ×2/3 → O(log₍₃⁄₂₎ n),与二分同阶。
坡度二分:比较 a[mid] 与 a[mid+1]——上坡去右、下坡去左,一个探针也能有方向感(log₂ n)。
实数版:凸/凹函数极值在实数域三分,固定轮数(如 100 轮)收敛到精度 ε。

至此查找大类五页收齐:找值 → 找边界 → 断崖找值 → 找答案 → 找峰。所有套路共享一个灵魂:每一步用 O(1) 的信息,安全地扔掉一大块候选。