LeetCode162-寻找峰值

题目链接

英文链接:https://leetcode.com/problems/find-peak-element/

中文链接:https://leetcode-cn.com/problems/find-peak-element/

题目详述

峰值元素是指其值大于左右相邻值的元素。

给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。

数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。

你可以假设 nums[-1] = nums[n] = -∞。

示例 1:

1
2
3
输入: nums = [1,2,3,1]
输出: 2
解释: 3 是峰值元素,你的函数应该返回其索引 2。

示例 2:

1
2
3
4
输入: nums = [1,2,1,3,5,6,4]
输出: 1 或 5
解释: 你的函数可以返回索引 1,其峰值元素为 2;
或者返回索引 5, 其峰值元素为 6。

说明:

你的解法应该是 O(logN) 时间复杂度的。

题目详解

  • 二分查找的条件为查找区间满足有界性,即一半区间满足要求,另一半区间不满足要求。
  • 在二分查找过程中,把边界值小的那一部分砍掉,留下大的所在的区间。这是因为大的所在的区间必然会存在峰值,而另一半可能存在,也可能不存在。由于题目要求任何一个峰值即可,我们往必然会存在峰值的区间走确定会得到一个峰值。
  • 本题二分的有界性体现在是否区间是否确定存在峰值。
  • 采用 midmid + 1 进行比较是为了防止越界,mid 取得是区间个数为偶数的中间左边那个数。也可以运用 midmid - 1 进行比较,这时 mid = l + r + 1 >>> 1;mid 取得是区间个数为偶数的中间右边那个数。
  • 时间复杂度为 O(logN)
1
2
3
4
5
6
7
8
9
10
11
12
public class LeetCode_00162 {

public int findPeakElement(int[] nums) {
int l = 0, r = nums.length - 1;
while (l < r) {
int mid = l + r >>> 1;
if (nums[mid] > nums[mid + 1]) r = mid;
else l = mid + 1;
}
return r;
}
}