# 查找数组中的局部最小值
对于查找数组中的局部最小值可以分为如下**三种情况**,即:
- 对于数组首部:如果`arr[0] < arr[1]`,那么`arr[0]`为局部最小;
- 对于数组尾部:如果`arr[n-2] > arr[n-1]`,那么`arr[n-1]`为局部最小值;
- 对于其余任意位置`i`:需要满足`arr[i-1]>arr[i]`,且`arr[i]<arr[i+1]`;
那么编程应该首先考虑边界问题,最后对于非边界情况满足下图:
![](https://img.kancloud.cn/cd/77/cd776eb96fc0ded4d526a8db682cadf7_552x359.png)
那么也就是说,如果在首尾边界都没有找到局部最小值,而我们确定数列中存在局部最小。那么应该满足上图的情况。
那么,在下标`[2...n-3]`位置中必然存在满足条件的局部最小值。所以本题可以使用二分来进行查找。即代码为:
~~~
public int localMinimum(int[] arr) {
int len = 0;
if (arr == null || (len = arr.length) == 0 || len < 2) return -1;
// 首尾边界情况
if (arr[0] < arr[1]) return 0;
if (arr[len - 1] < arr[len - 2]) return len - 1;
int left = 0, right = arr.length - 1;
while (left < right) {
int mid = (left + right) / 2;
if (mid >= 1 && mid < len - 1 &&
arr[mid] < arr[mid + 1] && arr[mid] < arr[mid - 1]) { // 当前满足局部最小值
return mid;
} else if (mid >= 1 && arr[mid] > arr[mid - 1]) { // 局部最小值在左侧
right = mid - 1;
} else if (mid < len - 1 && arr[mid] > arr[mid + 1]) { // 局部最小值在右侧
left = mid + 1;
}
}
return -1;
}
~~~
对应情况可以继续用下面的图表示:
![](https://img.kancloud.cn/43/82/43828667503517470a59b7792e6f5fb9_824x416.png)
可以参考:[162. 寻找峰值 - 力扣(LeetCode) (leetcode-cn.com)](https://leetcode-cn.com/problems/find-peak-element/)