leetcode162. Find Peak Element

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011732358/article/details/84891474

题目链接
题目:峰值元素是指其值大于左右相邻值的元素。
给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。
数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞。

示例 1:
输入: nums = [1,2,3,1]
输出: 2
解释: 3 是峰值元素,你的函数应该返回其索引 2。

示例 2:
输入: nums = [1,2,1,3,5,6,4]
输出: 1 或 5
解释: 你的函数可以返回索引 1,其峰值元素为 2;
或者返回索引 5, 其峰值元素为 6。
说明:
你的解法应该是 O(logN) 时间复杂度的。
思路:我的解法是 O ( n ) O(n) 貌似并不符合说明,但是不知道为啥还是过了,就写一下思路吧:由于峰值是先增后减,所以用up来标志是否增加,1代表增;用down来代表是否先增后减,即 如果down之前up为1 down才能赋值为1,否则只能是0,所以直接down=up就好。在提交过程中,发现如果序列单调递增,,,其实也存在峰值,就是序列的最后一个元素,所以用down2来标志该序列是否为单调递增的,如果down2为0 说明单调递增,返回最后一个元素下标即可。

class Solution {
    public int findPeakElement(int[] nums) {
        int len = nums.length;
        int up = 0;
        int down = 0;
        int down2 = 0;
        List<Integer> list = new ArrayList<>();
        for(int i = 1; i < len; i++){
            if(nums[i] > nums[i-1]){
                up = 1;
            }else{
                down = up;
                down2 = 1;
            }
            if(up * down == 1){
                return i-1;
            }
        }
        if(down2 == 0){
            return len - 1;
        }
        return 0;
    }
}

在这里插入图片描述

看完别人的思路,瞬间凌乱了,原来对题意理解也不够深入,忽略了题目最后一句话“你可以假设 nums[-1] = nums[n] = -∞。”,同样的 O ( n ) O(n) 解法,代码也是差距如此之大。

public class Solution {
    public int findPeakElement(int[] nums) {
        for (int i = 0; i < nums.length - 1; i++) {
            if (nums[i] > nums[i + 1])
                return i;
        }
        return nums.length - 1;
    }
}

接下来整一波 O ( l o g n ) O(logn)的算法
别人思路:已知题目最左端和最右端元素均无限小,中间元素比两侧都要大,那么本题中一定存在一个峰元素。所以不管中间有多少波峰,只要找到峰元素,我们只需找到刚刚开始下降而未下降的位置,二分查找即可。时间复杂度 O ( l o g n ) O(logn)
参考:https://blog.csdn.net/happyaaaaaaaaaaa/article/details/51590056

public class Solution {
    public int findPeakElement(int[] nums) {
        int left = 0;
        int right = nums.length - 1;
        int mid;
        while(left < right){
            mid = (left + right) / 2;
            if(nums[mid] < nums[mid+1]){
                left = mid + 1;
            }else{
                right = mid;
            }
        }
        return left;
    }
}

猜你喜欢

转载自blog.csdn.net/u011732358/article/details/84891474
今日推荐