1. 三分查找算法概述
三分查找(Ternary Search)是一种用于在单峰函数或单峰数组中寻找极值的高效算法。作为一名长期从事算法开发的工程师,我经常需要在各种优化问题中使用这种技术。与大家熟悉的二分查找不同,三分查找通过将搜索区间分成三部分来逐步缩小极值所在的范围。
在实际工程中,三分查找最常见的应用场景包括:
- 寻找单峰函数的极值点(如机器学习中的损失函数优化)
- 处理具有峰值特性的数据序列(如信号处理中的峰值检测)
- 解决各种数值优化问题(如参数调优、资源分配等)
提示:单峰结构指的是序列先严格递增到某个顶点后严格递减,或者先递减后递增。这种特性保证了极值的唯一性。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 单峰结构与算法原理
2.1 单峰数组的特性分析
单峰数组具有明确的数学定义:存在一个索引p,使得数组在[0,p]区间内单调递增,在[p,n-1]区间内单调递减。例如数组[1, 3, 7, 12, 9, 5, 2]就是一个典型的单峰数组,其峰值位于索引3(值为12)。
在实际项目中识别单峰数组时,我通常会进行以下验证:
- 检查数组是否严格递增到某点后严格递减
- 确认峰值是否唯一(允许相邻相等值但不推荐)
- 处理边界情况(如全递增或全递减数组)
2.2 三分查找的核心思想
三分查找的基本原理是通过比较两个中间点的值来决定极值所在的区间。具体步骤为:
-
将当前区间[left, right]划分为三等分,计算两个分界点:
mid1 = left + (right-left)/3
mid2 = right - (right-left)/3 -
比较arr[mid1]和arr[mid2]:
- 如果arr[mid1] < arr[mid2],说明极值在[mid1, right]区间
- 否则,极值在[left, mid2]区间
-
重复上述过程直到区间足够小(通常剩余2-3个元素)
这种分治策略的时间复杂度为O(log₃n),虽然理论上与二分查找的O(log₂n)同阶,但在实际应用中,三分查找针对单峰问题的效率往往更高。
3. Go语言实现细节
3.1 迭代版本实现
go复制func TernarySearchIter(arr []int) int {
left := 0
right := len(arr) - 1
for right-left > 2 {
mid1 := left + (right-left)/3
mid2 := right - (right-left)/3
if arr[mid1] < arr[mid2] {
left = mid1
} else {
right = mid2
}
}
maxIndex := left
for i := left + 1; i <= right; i++ {
if arr[i] > arr[maxIndex] {
maxIndex = i
}
}
return maxIndex
}
这个迭代版
