题目来源
A peak element is an element that is greater than its neighbors.
Given an input array where num[i] ≠ num[i+1]
, find a peak element and return its index.
The array may contain multiple peaks, in that case return the index to any one of the peaks is fine.
You may imagine that num[-1] = num[n] = -∞
.
For example, in array [1, 2, 3, 1]
, 3 is a peak element and your function should return the index number 2.
一看这题目,挺简单的啊,最先想到的方法就是从前往后遍历,遍历到该元素比周围元素大或者小的就返回。第一个和最后一个特殊处理一下。直接AC了。复杂度O(n)。
class Solution {
public:
int findPeakElement(vector<int>& nums) {
int n = nums.size();
if (n == 1 || nums[0] > nums[1])
return 0;
if (nums[n-1] > nums[n-2])
return 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[i] > nums[i-1] && nums[i] > nums[i+1])
return i;
}
return -1;
}
};
好吧,肯定有O(logN)的做法,看看去。
先来个O(n)的,但是简洁的很啊==
class Solution {
public:
int findPeakElement(vector<int>& nums) {
int n = nums.size();
for (int i=1; i<n; i++) {
if (nums[i] < nums[i-1])
return i-1;
}
return n-1;
}
};
还有O(logN)的,之前就没想到可以用二分查找,这不是无序的吗?怎么用二分呢?看看代码就知道了。
class Solution {
public:
int findPeakElement(vector<int>& nums) {
int n = nums.size();
int l = 0, r = n - 1;
int mid1 = 0, mid2 = 0;
while (l < r) {
mid1 = (l + r) / 2;
mid2 = mid1 + 1;
if (nums[mid1] < nums[mid2])
l = mid2;
else
r = mid1;
}
return l;
}
};
实际上也不难看懂,比如找到mid1 and mid2
是递增的,那么mid2及其后面一定有个极值点,因为最后一点是递减的。同理mid1 and mid2
是递减的,那么mid1及其前面一定有个极值点,因为第一点是递增的。