从数组中找到一个峰值,对于n个元素的数组,认为nums[-1] = nums[n] = -∞。峰值的含义:和它相邻的元素相比,比它左右元素值都大,就是峰值,返回峰值的下标。数组中可能有多个峰值,找到一个返回即可。
例如:
Input: nums = [1,2,3,1]
Output: 2 (下标为2的元素是一个峰值)
难度:【medium】
思路:(方法1)最先想到的方法就是暴力方法。这道题用暴力破解速度也不慢,而且可以通过。只要把左边界,有边界,数组元素个数为1,这几种条件考虑清楚就好。(方法2)看了讨论中的方法,发现有简化的方法。从数组下标1开始,每次遍历对当前元素和前一个元素做比较,如果比前一个元素小,那么就可以断定前一个元素是一个峰值了。(这里要思考一下)。(方法3)也是在讨论中看到的,使用二分搜索的思想。(也是值得思考的,二分查找的应用很多)
方法1:
int findPeakElement(vector<int>& nums) {
int n = nums.size();
int i = 0;
if (n == 1) { return 0; }
for (; i < n; ++i) {
if ((i == 0 && i < n - 1 && nums[i] > nums[i + 1]) ||
(i == n - 1 && i > 0 && nums[i] > nums[i - 1]) ||
(i > 0 && i < n - 1 && nums[i] > nums[i - 1] && nums[i] > nums[i + 1])) {
break;
}
}
return i;
}
方法2:
// [方法2.1] i 从 1 开始遍历
int findPeakElement(vector<int>& nums) {
for (int i = 1; i < nums.size(); ++i) {
if (nums[i] < nums[i - 1]) {
return i - 1;
}
}
return nums.size() - 1;
}
// [方法2.2] i 从0开始遍历
int findPeakElement(vector<int>& nums) {
for (int i = 0; i < nums.size() - 1; ++i) {
if (nums[i] > nums[i + 1]) {
return i;
}
}
return nums.size() - 1;
}
方法3:
int findPeakElement(vector<int>& nums) {
int low = 0;
int high = nums.size() - 1;
while (low < high) {
int mid1 = (low + high) / 2;
int mid2 = mid1 + 1;
if (nums[mid1] < nums[mid2]) {
low = mid2;
} else {
high = mid1;
}
}
return low;
}