目录
一、寻找峰值的示例
二、官方实现代码及解释
1、官方测试结果:
2、代码解释:
3、解题思路:
三、我的暴力解决
1、测试一:
2、测试二:
3、最终“暴力求解”代码:
4、官网提交测试通过:
5、解题思路:
四、c++函数max_element()解决
1、函数使用介绍:
2、max_element() 峰值寻找完整代码:
一、寻找峰值的示例
示例 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]
二、官方实现代码及解释
1、官方测试结果:
2、代码解释:
class Solution {
public:
int findPeakElement(vector<int>& nums) {
//1、准备工作:获得nums、生成随机索引值
//随机索引值在一定概率上可以快速得到峰值,最好情况是刚好随机到峰值数的索引,最差情况是刚好随机到距离峰值最远的元素
int n = nums.size(); //得到nums数据长度
int idx = rand() % n; //随机生成0~n-1的索引idx值
//2、设计函数get,输入i,得到数组对(0/1, nums[i])
// 辅助函数,输入下标 i,返回一个二元组 (0/1, nums[i])
// 方便处理 nums[-1] 以及 nums[n] 的边界情况
auto get = [&](int i)->pair<int,int>{
if(i==-1||i==n)
{
return{0,0};
}
return {1,nums[i]};
};
详细解释lambda表达式:
- get是函数名
- [&]是所有变量以引用捕获的方式传入到表达式中,也就是i传入后可访问、修改
- (int i)是参数列表,这里参数是整型
- -> pair<int,int>是返回值类型为pair<int,int>,定义为两个int型的数据对
- {} 里面是函数体,此处返回(0/1, nums[i]),0是超过边界的数对,1是符合边界0~n-1的所有数对
while(!(get(idx - 1)<get(idx)&&get(idx)>get(idx + 1))){
if(get(idx)<get(idx+1))
{
idx += 1;
}
else
{
idx -= 1;
}
}
return idx;
}
};
这里get获得的是(1,nums(i))的pair数据对,pair的first值都是1,所以大小比较的时候对pair的second值进行大小的比较,这个可以mark一下!
3、解题思路:
(1)当不是峰值时,峰值出现在idx的左边或者右边,索引值idx<idx+1时峰值索引变成idx+1,相反idx<idx-1,峰值索引变为idx-1。
(2)i值大于i+1且i值大于i-1
三、我的暴力解决
class Solution {
public:
int findPeakElement(vector<int>& nums) {
int n=nums.size();
int idx = 0;
for(int i = 1;i<n-1;i++)
{
if(n==2)
{
if(nums[i] > nums[i-1])
{
idx = i;
break;
}
else if(nums[i] < nums[i-1])
{
idx = i-1;
break;
}
}
if(nums[i] > nums[i+1] && nums[i] > nums[i-1]) {
idx = i;
break; }
}
return idx;
}
};
1、测试一:
测试用例失败:nums =[1,2],输出0,期望是1
调试一下发现循环条件"n<n-1",当n=2时,n<1,n从1开始,所以没有进入循环判断"if(n==2)"的条件,测试nums =[1,2]案例失败。
修改while循环条件,得到正确输出:
但是,似乎不行呀,执行nums=[1,2,3,4]的时候,没有峰值,所以出错
所以,我发现,官方给的答案确实有他的道理!!!这里没考虑峰值为单边的情况,比如只有上坡或者只有下坡,单独“if (nums[i] > nums[i + 1] && nums[i] > nums[i - 1])”就会报以上的错误了。
2、测试二:
考虑新增上下坡的情况判断
if (i + 1 == n)
{
if (nums[i] > nums[i - 1])
{
idx = i;
break;
}
if (nums[i] < nums[i - 1])
{
break;
}
}
Yes,测试下坡vector<int> nums = {4,3,2,1}通过: 测试上坡vector<int> nums = {1,2,3,4}通过:
3、最终“暴力求解”代码:
在vs上测试代码Solution.cpp、Solution.h、 main.cpp
Solution.cpp
#include "Solution.h"
int Solution::findPeakElement(vector<int>& nums)
{
int n = nums.size();
int idx = 0;
for (int i = 1; i < n ; i++)
{
if (n == 2)
{
if (nums[i] > nums[i - 1])
{
idx = i;
break;
}
else if (nums[i] < nums[i - 1])
{
idx = i - 1;
break;
}
}
if (i + 1 == n)
{
if (nums[i] > nums[i - 1])
{
idx = i;
break;
}
if (nums[i] < nums[i - 1])
{
break;
}
}
if (nums[i] > nums[i + 1] && nums[i] > nums[i - 1]) {
idx = i;
break;
}
}
return idx;
}
Solution.h
#pragma once
#include<vector>
using namespace std;
class Solution
{
public:
int findPeakElement(vector<int>& nums);
};
mian.cpp
#include<iostream>
using namespace std;
#include"Solution.h"
int main()
{
vector<int> nums = {4,3,2,1};
Solution Func;
int index = Func.findPeakElement(nums);
cout << index << endl;
}
4、官网提交测试通过:
5、解题思路:
- 首先想到nums的峰值元素满足条件1:if(nums[i]>nums[i+1]&&nums[i]<nums[i-1]);
- 提交1后,nums=[1]只有一个元素时,idx应该返回0;所以idx初始值为0;
- 提交2后,nums=[1,2]只有两个元素时,idx应该等于较大元素,增加两个元素时条件2:if(n==2)时idx=较大值索引;
- 提交3后,只有上下坡报错,新增条件3:nums=[1,2,3,4]上坡时,idx应该等于最后一个元素的索引;下坡nums=[4,3,2,1]时,idx应该等于最后一个元素的索引;
- 注意for循环范围for (int i = 1; i < n ; i++)。
四、c++函数max_element()解决
我真的栓Q了,原来函数解决这么简单哦!
1、函数使用介绍:
max_element()与min_element()分别用来求vector容器的最大元素和最小元素的位置。
1)vector容器
vector<int> n;
int maxPosition = max_element(n.begin(),n.end()) - n.begin(); //最大值下标
int minPosition = min_element(n.begin(),n.end()) - n.begin();//最小值下标
2)普通数组
int a[]={1,2,3,4};
int maxPosition = max_element(a,a+4) - a; //最大值下标
int minPosition = min_element(a,a+4) - a;//最小值下标
3)最大值最小值
int maxValue1 = *max_element(nums.begin(), nums.end()); //vector最大值
int minValue1 = *min_element(nums.begin(), nums.end());//vector最小值
int maxValue2 = *max_element(a, a + 4); //a[]最大值
int minValue2 = *min_element(a, a + 4);//a[]最小值
2、max_element() 峰值寻找完整代码:
#include<iostream>
using namespace std;
#include <algorithm>
int main()
{
vector<int> nums = {4,3,2,1};
int index = max_element(nums.begin(), nums.end()) - nums.begin(); //最大值下标
cout <<"vector下最大值下标:" << index << endl;
int a[] = { 4,3,2,1 };
int maxIdx = max_element(a, a + 4) - a;
cout << "a[] 下最大值下标:" << maxIdx << endl;
int maxValue1 = *max_element(nums.begin(), nums.end()); //最大值
int minValue1 = *min_element(nums.begin(), nums.end());//最小值
int maxValue2 = *max_element(a, a + 4); //最大值
int minValue2 = *min_element(a, a + 4);//最小值
cout << "vector下的max值:" << maxValue1 << " min值:" << minValue1 << endl;
cout << "a[] 下的max值:" << maxValue1 << " min值:" << minValue2 << endl;
}