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 ;
    }
}

扩展:
在这里插入图片描述

posted @   青松城  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示