题目
给定一个数组,找到其中局部最小解,局部最小解定义,一定比它左右两边的数小,如果左边不存在则比右边的小,如果右边不存在则比左边的小
- 先对边界情况进行判断,即数组的头部和尾部先判断是否是最优解,如果都不是,说明数组一定是一个左边上升,右边下降的趋势,那么中间就一定至少存在一个波谷
- 因为一个至少存在一个波谷,所以所在的点一定在波谷的上升曲线上或者下降曲线上
- 在上升曲线上就往左找,在下降曲线上就往右找
- 所以二分法不一定需要有序数组,只要能满足分成两半的就行
function part(arr) {
// 头部上升趋势
if (arr[0] < arr[1]) {
return 0
}
// 尾部下降趋势
if (arr[arr.length - 1] < arr[arr.length - 2]) {
return arr.length - 1
}
// 头部下降尾部上升趋势,期间一定存在局部最优解(一个或多个波谷),因为一定存在最低点
// 因为一个至少存在一个波谷,所以所在的点一定在波谷的上升曲线上或者下降曲线上
// 在上升曲线上就往左找,在下降曲线上就往右找
let left = 1,
right = arr.length - 2,
mid
// 去找比左右两边都小的数(波谷)
while (left < right) {
mid = (left + (right - left)) >> 1
// 在上升曲线上,往左找
if (arr[mid] > arr[mid - 1]) {
right = mid - 1
} else if (arr[mid] > arr[mid + 1]) {
// 在下降曲线上,往右找
left = mid + 1
} else {
// 找到了比左边小又比右边小的数
return mid
}
}
return mid
}