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.

Note:

Your solution should be in logarithmic complexity.

这道题是求数组的一个峰值,如果这里用遍历整个数组找最大值肯定会出现Time Limit Exceeded,但题目中说了这个峰值可以是局部的最大值,所以我们只需要找到第一个局部峰值就可以了。所谓峰值就是比周围两个数字都大的数字,那么只需要跟周围两个数字比较就可以了。既然要跟左右的数字比较,就得考虑越界的问题,题目中给了nums[-1] = nums[n] = -∞,那么我们其实可以把这两个整型最小值直接加入到数组中,然后从第二个数字遍历到倒数第二个数字,这样就不会存在越界的可能了。由于题目中说了峰值一定存在,那么有一个很重要的corner case我们要注意,就是当原数组中只有一个数字,且是整型最小值的时候,我们如果还要首尾垫数字,就会形成一条水平线,从而没有峰值了,所以我们对于数组中只有一个数字的情况在开头直接判断一下即可,参见代码如下:

C++ 解法一:

class Solution {
public:
int findPeakElement(vector<int>& nums) {
if (nums.size() == ) return ;
nums.insert(nums.begin(), INT_MIN);
nums.push_back(INT_MIN);
for (int i = ; i < (int)nums.size() - ; ++i) {
if (nums[i] > nums[i - ] && nums[i] > nums[i + ]) return i - ;
}
return -;
}
};

Java 解法一:

class Solution {
public int findPeakElement(int[] nums) {
if (nums.length == 1) return 0;
int[] newNums = new int[nums.length + 2];
System.arraycopy(nums, 0, newNums, 1, nums.length);
newNums[0] = Integer.MIN_VALUE;
newNums[newNums.length - 1] = Integer.MIN_VALUE;
for (int i = 1; i < newNums.length - 1; ++i) {
if (newNums[i] > newNums[i - 1] && newNums[i] > newNums[i + 1]) return i - 1;
}
return -1;
}
}

我们可以对上面的线性扫描的方法进行一些优化,可以省去首尾垫值的步骤。由于题目中说明了局部峰值一定存在,那么实际上可以从第二个数字开始往后遍历,如果第二个数字比第一个数字小,说明此时第一个数字就是一个局部峰值;否则就往后继续遍历,现在是个递增趋势,如果此时某个数字小于前面那个数字,说明前面数字就是一个局部峰值,返回位置即可。如果循环结束了,说明原数组是个递增数组,返回最后一个位置即可,参见代码如下:

C++ 解法二:

class Solution {
public:
int findPeakElement(vector<int>& nums) {
for (int i = ; i < nums.size(); ++i) {
if (nums[i] < nums[i - ]) return i - ;
}
return nums.size() - ;
}
};

Java 解法二:

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

由于题目中提示了要用对数级的时间复杂度,那么我们就要考虑使用类似于二分查找法来缩短时间,由于只是需要找到任意一个峰值,那么我们在确定二分查找折半后中间那个元素后,和紧跟的那个元素比较下大小,如果大于,则说明峰值在前面,如果小于则在后面。这样就可以找到一个峰值了,代码如下:

C++ 解法三:

class Solution {
public:
int findPeakElement(vector<int>& nums) {
int left = , right = nums.size() - ;
while (left < right) {
int mid = left + (right - left) / ;
if (nums[mid] < nums[mid + ]) left = mid + ;
else right = mid;
}
return right;
}
};

Java 解法三:

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

类似题目:

Peak Index in a Mountain Array

参考资料:

https://leetcode.com/problems/find-peak-element

https://leetcode.com/problems/find-peak-element/discuss/50232/find-the-maximum-by-binary-search-recursion-and-iteration

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Find Peak Element 求数组的局部峰值的更多相关文章

  1. [LintCode] Find Peak Element 求数组的峰值

    There is an integer array which has the following features: The numbers in adjacent positions are di ...

  2. LeetCode Find Peak Element 找临时最大值

    Status: AcceptedRuntime: 9 ms 题意:给一个数组,用Vector容器装的,要求找到一个临时最高点,可以假设有num[-1]和num[n]两个元素,都是无穷小,那么当只有一个 ...

  3. LeetCode Find Peak Element

    原题链接在这里:https://leetcode.com/problems/find-peak-element/ 题目: A peak element is an element that is gr ...

  4. LeetCode Find Peak Element [TBD]

    说要写成对数时间复杂度,算了想不出来,写个O(n)的水了 class Solution { public: int findPeakElement(const vector<int> &a ...

  5. LeetCode: Find Peak Element 解题报告

    Find Peak Element A peak element is an element that is greater than its neighbors. Given an input ar ...

  6. [LeetCode] Find Peak Element 二分搜索

    A peak element is an element that is greater than its neighbors. Given an input array where num[i] ≠ ...

  7. ✡ leetcode 169. Majority Element 求出现次数最多的数 --------- java

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  8. leetcode——169 Majority Element(数组中出现次数过半的元素)

    Given an array of size n, find the majority element. The majority element is the element that appear ...

  9. Lintcode: Find Peak Element

    There is an integer array which has the following features: * The numbers in adjacent positions are ...

随机推荐

  1. u-boot源码分析之C语言段

    题外话: 最近一直在学习u-boot的源代码,从代码量到代码风格,都让我认识到什么才是真正的程序.以往我所学到的C语言知识和u-boot的源代码相比,实在不值一提.说到底,机器都是0和1控制的.感觉这 ...

  2. FFmpeg学习3:播放音频

    参考dranger tutorial,本文将介绍如何使用FFmpeg解码音频数据,并使用SDL将解码后的数据输出. 本文主要包含以下几方面的内容: 关于播放音频的需要的一些基础知识介绍 使用SDL2播 ...

  3. 关系数据库SQL之可编程性触发器

    前言 前面关系数据库SQL之可编程性函数(用户自定义函数)一文提到关系型数据库提供了可编程性的函数.存储过程.事务.触发器及游标,前文已介绍了函数.存储过程.事务,本文来介绍一下触发器的使用.(还是以 ...

  4. JS 传播事件、取消事件默认行为、阻止事件传播

    1.事件处理程序的返回值 通常情况下,返回值false就是告诉浏览器不要执行这个事件相关的默认操作.例如,表单提交按钮的onclick事件处理程序能通过返回false阻止浏览器提交表单,再如a标签的o ...

  5. $_SERVER

    $_SERVER[‘HTTP_X_REWRITE_URL’] 和$_SERVER[‘REQUEST_URI’]的区别 php4.4.0不支持 $_SERVER[‘REQUEST_URI’],php5. ...

  6. jquery的选择器

    一.基本选择器 1.$("#id") id选择器,返回单个元素 2.$(".class") class选择器,返回集合元素 3.$("element& ...

  7. 移动web开发调试工具AlloyLever介绍

    简介 web调试有几个非常频繁的刚需:看log.看error.看AJAX发包与回包.其他的如timeline和cookie以及localstorage就不是那么频繁,但是AlloyLever都支持.如 ...

  8. 【搬砖】安卓入门(2)- Java开发编程基础--进制转换和运算符

    02.01_Java语言基础(常量的概述和使用)(掌握) A:什么是常量 在程序执行的过程中其值不可以发生改变 B:Java中常量的分类 字面值常量 自定义常量(面向对象部分讲) C:字面值常量的分类 ...

  9. Android系统属性简介

    查看Android源码你会发现,代码中大量存在:SystemProperties.set()/SystemProperties.get():通过这两个接口可以对系统的属性进行读取/设置,顾名思义系统属 ...

  10. iOS 如何使用Safari浏览器打开app

    1.首先在info.plist添加一个键值对,如下图 或 2.在appdelegate.m文件如下方法写代码 -(BOOL)application:(UIApplication*)app openUR ...