162. Find Peak Element

Description

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

Given an input array where num[i] ≠ num[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 num[-1] = num[n] = -∞.

For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2.

click to show spoilers.

Note:

Your solution should be in logarithmic complexity.

Credits:
Special thanks to @ts for adding this problem and creating all test cases.

Solution

首先注意这道题给定的条件num[i] ≠ num[i+1],说明不存在连续相等的元素,所以不用考虑元素相等的情况。

Iterative, time O(n), space O(1)

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

Binary search, time O(logn), space O(1)

我们可以发现两个规律,一个是一定存在峰值元素(因为题目给定不存在连续相等的元素,那么数组不可能所有元素都想等,所以一定有峰值,要么在头要么在尾,要么在中间),另一个是在遍历查找过程中对于某个元素之前的所有元素是递增的.其实这两个描述并不准确.我尝试用如下语句来描述这个规律:

规律一:如果nums[i] > nums[i+1],则在i之前一定存在峰值元素
规律二:如果nums[i] < nums[i+1],则在i之后一定存在峰值元素

我们可以采用二分查找的方式设计如下算法,注意如果存在多个峰值要求返回第一个,所以这道题就是找满足X条件的第一个位置:

算法

  1. front设为首元素,back设为尾元素
  2. 如果front==end,返回front
  3. 取中间元素center,判定其是否比后面的元素大,是则4,否则5
  4. back=center,跳到1
  5. front=center+1,跳到1
class Solution {
    public int findPeakElement(int[] nums) {
        int left = 0;
        int right = nums.length - 1;
        
        while (left <= right) {
            int mid = (left + right) / 2;
            
            if (mid < nums.length - 1 && nums[mid] < nums[mid + 1]) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        
        return left;
    }
}

你可能感兴趣的:(162. Find Peak Element)