19.<tag-数组和二分查找>-lt.162- 寻找峰值 0.9
lt.162- 寻找峰值
[案例需求]
[思路分析]
- 题目要求o(logN), 二分!
- 题目要求我们找出一组数字序列中的任一峰值, 也就是
找到这一组数字中任意一个数, 这个数的左右相邻的数都小于它.
- 其实这道题里面最最重要的线索就是这句话, 你可以假设 nums[-1] = nums[n] = -∞ 。 , 这就意味着只要我们保证了一边的上坡, 就可以找到峰值.
再重复一遍:
这道题,最最最重要的是条件,条件,条件,两边都是负无穷,数组当中可能有很多波峰,也可能只有一个,如果尝试画图,就跟股票信息一样,没有规律,如果根据中点値判断我们的二分方向该往何处取, 这道题还有只是返回一个波峰。你这样想,中点所在地方,可能是某座山的山峰,山的下坡处,山的上坡处,如果是山峰,最后会二分终止也会找到,关键是我们的二分方向,并不知道山峰在我们左边还是右边,送你两个字你就明白了,爬山(没错,就是带你去爬山),如果你往下坡方向走,也许可能遇到新的山峰,但是也许是一个一直下降的坡,最后到边界。但是如果你往上坡方向走,就算最后一直上的边界,由于最边界是负无穷,所以就一定能找到山峰,总的一句话,往递增的方向上,二分,一定能找到,往递减的方向只是可能找到,也许没有
[代码实现]
class Solution {
public int findPeakElement(int[] nums) {
//题目这句话很重要, nums[-1] = nums[n] = -无穷,
//这意味着: 只要数组中存在一个元素比相邻元素大, 那么沿着它一定可以找到一个峰值!
//因为数组的两边都是相当于无限小的数.
int len = nums.length;
int left = 0;
int right = len - 1;
while(left < right){
int mid = left + ((right - left) >> 1);
//mid是用来寻找其中一边的峰值下坡
if(nums[mid] < nums[mid + 1]){ /
left = mid + 1;
}else{
right = mid;
}
}
return left;
}
}
[代码示例二, 按照二分模板的写法]
class Solution {
public int findPeakElement(int[] nums) {
int left = 0;
int len = nums.length;
int right = len - 1;
while(left <= right){
//二分, 一边是大于mid的, 一边是小于mid的
int mid = left + ((right - left) >> 1);
// 右边大
if(mid + 1 < len && nums[mid] < nums[mid + 1]){
left = mid + 1;
}else{ //左边大
right = mid - 1;
}
}
return left ;
}
}
扩展:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律