LeetCode Top Interview Questions 162. Find Peak Element (Java版; Medium)

welcome to my blog

LeetCode Top Interview Questions 162. Find Peak Element (Java版; Medium)

题目描述
A peak element is an element that is greater than its neighbors.

Given an input array nums, where nums[i] ≠ nums[i+1], find a peak element and return its index.

The array may contain multiple peaks, in that case return the index to any one of the peaks is fine.

You may imagine that nums[-1] = nums[n] = -∞.

Example 1:

Input: nums = [1,2,3,1]
Output: 2
Explanation: 3 is a peak element and your function should return the index number 2.
Example 2:

Input: nums = [1,2,1,3,5,6,4]
Output: 1 or 5 
Explanation: Your function can return either index number 1 where the peak element is 2, 
            or index number 5 where the peak element is 6.
第一次做; 二分查找法, O(logN); 这道题虽然不是有序数组, 但仍然可以用二分查找法, 因为nums[-1]和nums[n]有助于决定单调性大趋势; 核心: 明确left和right指向位置的含义
/*
先来个O(N)的解法
感觉存在O(logN)的解法, 也就是得用二分法, 但是二分法的if else是什么? mid和什么比? 没有大小关系啊
由于nums[-1]==nums[n]==负无穷, 实际上可以让mid和mid+1或者mid-1比, 选择一个进行比较(相邻两个数没有相等的情况)即可, 比如选择mid-1, 根据单调性的变化
如果nums[mid] < nums[mid-1], 可知nums[-1,mid]至少有一个peak(比如先递增再递减), 那么左侧一定有peak
如果nums[mid] > nums[mid-1], 可知nums[mid,n]的单调性大趋势是先递增再递减, 那么右侧一定有peak

细节:代码中让nums[mid]和nums[mid+1]比较, 因为使用nums[mid-1]可能会越界, 比如left=0, right=1时, mid=0, 此时mid-1=-1就越界了! 熟能生巧
细节:left和right最终的指向是什么? 本题是peak的位置
*/
class Solution {
    public int findPeakElement(int[] nums) {
        int n = nums.length;
        //细节: left和right最终指向peak的位置
        int left=0, right=n-1, mid;
        while(left<right){
            mid = left + ((right-left)>>1);
            //peak在
            if(nums[mid]>nums[mid+1])
                right=mid;
            else
                left=mid+1;
        }
        return left;
    }
}
第一次做; 暴力, O(N)
/*
先来个O(N)的解法
感觉存在O(logN)的解法, 也就是得用二分法, 但是二分法的if else是什么? mid和什么比? 没有大小关系啊
*/
class Solution {
    public int findPeakElement(int[] nums) {
        int n = nums.length;
        if(n==1)
            return 0;
        if(nums[0]>nums[1])
            return 0;
        if(nums[n-2]<nums[n-1])
            return n-1;
        for(int i=1; i<n-1; i++){
            if(nums[i]>nums[i-1] && nums[i]>nums[i+1])
                return i;
        }
        return -1;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值