描述
给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个所在位置即可。
1.峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于
2.假设 nums[-1] = nums[n] = -\infty−∞
3.对于所有有效的 i 都有 nums[i] != nums[i + 1]
4.你可以使用O(logN)的时间复杂度实现此问题吗?
数据范围:
1 \le nums.length \le 2\times 10^5 \1≤nums.length≤2×105
-2^{31}<= nums[i] <= 2^{31} - 1−231<=nums[i]<=231−1
如输入[2,4,1,2,7,8,4]时,会形成两个山峰,一个是索引为1,峰值为4的山峰,另一个是索引为5,峰值为8的山峰,如下图所示:
示例1
输入:
[2,4,1,2,7,8,4]复制
返回值:
1复制
说明:
4和8都是峰值元素,返回4的索引1或者8的索引5都可以
示例2
输入:
[1,2,3,1]复制
返回值:
2复制
说明:
3 是峰值元素,返回其索引 2
本题用暴力解法也能解
用二分的话需要观察其中的规律,因为题目假设了nums[-1] = nums[n] = -\infty−∞,因此使用二分法有上升趋势的一边一定存在峰值,且峰值为right
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param nums int整型vector
* @return int整型
*/
/*int findPeakElement(vector<int>& nums) {
// write code here
int n = nums.size();
if (n == 1) return 0;
if (n == 2) {
if (nums[0] > nums[1]) {
return 0;
} else {
return 1;
}
}
if (nums[0] > nums[1]) {
return 0;
}
int left = 0;
int right = n - 1;
for (int i = 1; i < n-1; i++) {
if (nums[i] > nums[i-1] && nums[i] > nums[i+1]) {
return i;
}
}
if (nums[n-1] > nums[n-2]) {
return n-1;
}
return -1;
}*/
int findPeakElement(vector<int>& nums) {
int n = nums.size();
int left = 0;
int right = n - 1;
while(left < right) {
int mid = (right-left)/2 + left;
//cout <<mid << endl;
if (nums[mid] > nums[mid-1] && nums[mid] > nums[mid+1]) {
return mid;
}
if (nums[mid] > nums[mid+1]) {
right = mid;
} else {
left = mid + 1;
}
}
return right;
}
};

京公网安备 11010502036488号