#162 Find Peak Element

Description

A peak element is an element that is strictly greater than its neighbors.

Given an integer array nums, find a peak element, and return its index. If the array contains multiple peaks, return the index to any of the peaks.

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

You must write an algorithm that runs in O(log n) time.

Examples

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: 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.

Constraints:

1 <= nums.length <= 1000
-231 <= nums[i] <= 231 - 1
nums[i] != nums[i + 1] for all valid i.

思路

这道题说是要找到“PeakIndex”,也就是峰值数字的序号
那他本质上就是一个找极大值的问题

因为题目限定了==O(log n)==的时间复杂度,所以这必然是一个用二分法查找的问题
我一开始想的比较复杂,觉得需要比较每个subList的头和尾,当数值发生降落的时候,则这段subList中必然存在peak;当这种情况不出现,就在两边分别寻找最大值,然后比较哪个更大,就用哪个,这个想法对应了代码1

但其实不用这样!
因为只要找极大值(而非最大值),那么当我们用middle分割了中部就能知道

  • 如果nums[middle] < nums[middle + 1],那么右侧必然出现极大值(并不意味着左边不出现!但题目要求只用找到一个即可)
  • 如果nums[middle] > nums[middle + 1],那么左侧必然出现极大值(至少nums[middle]的右侧已经比他小了)
    根据这一点,就可以写出很simple的代码,对应于代码2

代码

class Solution {
    int max = Integer.MIN_VALUE;
    public int PeakIndex(int[] nums, int start, int end){
        if(start == end || start == end - 1){
            int max_ = Math.max(nums[start], nums[end]);
            if (max_ < max)
                return -1;
            max = max_;
            if(nums[start] > nums[end])
                return start;
            else
                return end;
        }
        
        int mid = (start + end) / 2;
        if(nums[start] > nums[mid])
            return PeakIndex(nums, start, mid);
        if(nums[mid] < nums[mid + 1] && nums[mid + 1] > nums[end])
            return PeakIndex(nums, mid + 1, end);
        
        int left = PeakIndex(nums, start, mid);
        int right = PeakIndex(nums, mid + 1, end);
        
        if(right == -1)
            return left;
        else
            return right;
        
    }
    public int findPeakElement(int[] nums) {
        return PeakIndex(nums, 0, nums.length - 1);
    }
}
class Solution {
    public int PeakIndex(int[] nums, int start, int end){
        if(start == end || start == end - 1){
            if(nums[start] > nums[end])
                return start;
            else
                return end;
        }
        
        int mid = (start + end) / 2;
        if(nums[mid] > nums[mid + 1])
            return PeakIndex(nums, start, mid);
        else
            return PeakIndex(nums, mid + 1, end);
    }
    public int findPeakElement(int[] nums) {
        return PeakIndex(nums, 0, nums.length - 1);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值