leetcode 162 寻找峰值

题目原地址

题目比较简单,就是寻找数组中的极大值,由于假定数组的两端均为负无穷,所以如果数组为单调递增或者单调递减,极值就在数组的两端

如果遍历自然是很简单的,这里就不多说,这里说下logn复杂度的二分法解法

思路也比较简单,找到中点,然后判断中点与左右两边的大小,

  • 如果比左右两边都大,则这就是极值点,返回
  • 如果 nums[mid1]>nums[mid]>nums[mid+1]nums[mid-1]>nums[mid]>nums[mid+1] 则令right=mid,极值点在左侧
  • 如果 nums[mid1]<nums[mid]<nums[mid+1]nums[mid-1]<nums[mid]<nums[mid+1] 则令left=mid,极值点在右侧
  • 如果 比左右两侧都小,则随便往那一侧都可以(代码中默认往右)

结束的条件跟以往不同,如果left与right相邻了,则说明都到这一步了还没发现极值,所以极值肯定在他俩中间最大的那个

代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public:
int findPeakElement(vector<int>& nums) {
int n = nums.size();
if(n==1) return 0;
if(n==2) return nums[0]>nums[1]?0:1;
int l=0;int r=n-1;
while(r-l>1){
int m = (r+l)/2;
if(nums[m]>nums[m+1]&&nums[m]>nums[m-1]) return m;
else if(nums[m]<nums[m+1]) l=m;
else r=m;
}
return nums[l]>nums[r]?l:r;
}
};