峰值元素是指其值严格大于左右相邻值的元素。
给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞ 。
你必须实现时间复杂度为 O(log n) 的算法来解决此问题。
示例 1:
输入:nums = [1,2,3,1]
输出:2
解释:3 是峰值元素,你的函数应该返回其索引 2。
示例 2:输入:nums = [1,2,1,3,5,6,4]
输出:1 或 5
解释:你的函数可以返回索引 1,其峰值元素为 2;
或者返回索引 5, 其峰值元素为 6。
提示:
1 <= nums.length <= 1000
-231 <= nums[i] <= 231 - 1
对于所有有效的 i 都有 nums[i] != nums[i + 1]来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-peak-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
AC代码1:
class Solution {
public:
int findPeakElement(vector<int>& nums) {
if(nums.size()==1)
return 0;
if(nums[0]>nums[1])
return 0;
if(nums[nums.size()-1]>nums[nums.size()-2])
return nums.size()-1;
int left = 0;
int right = nums.size()-1;
while(left<right)
{
int mid = (left+right)/2;
if(nums[mid]<nums[mid+1])
left = mid;
else if(nums[mid]<nums[mid-1])
right = mid;
else
return mid;
}
return -1;
}
};
AC代码2:
class Solution {
public:
int findPeakElement(vector<int>& nums) {
int left = 0;
int right = nums.size()-1;
while(left<right) //根据下面的操作,循环结束条件只有可能是left=right
{
int mid = (left+right)/2;
if(nums[mid]<nums[mid+1])
{
//则在[mid+1 , right]这个区间内一定有峰值
left = mid+1;
}
else
{
//则nums[mid]一定大于nums[mid+1]
//则在[left,mid]这个区间内一定有峰值(包含mid
right = mid;
}
//每次循环都会缩小区间范围,
}
return left;
}
};
时间复杂度logn,则使用二分查找。这个题的关键是假设nums[0]左侧和nums[size-1]右侧都是负无穷,也就是说这个区间内是一定存在极大值的。还有就是任何相邻两个元素一定不同。二分的关键是如何缩小区间:先判断mid处,若nums[mid]小于nums[mid+1]则nums[mid+1]处及其右边一定存在峰值,反之亦然。每次循环都缩小范围,使得这个缩小之后的范围一定存在峰值。最后即可找到峰值。
344

被折叠的 条评论
为什么被折叠?



