[LeetCode] Find Peak Element 求数组的局部峰值
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
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Find Peak Element 求数组的局部峰值的更多相关文章
- [LintCode] Find Peak Element 求数组的峰值
There is an integer array which has the following features: The numbers in adjacent positions are di ...
- LeetCode Find Peak Element 找临时最大值
Status: AcceptedRuntime: 9 ms 题意:给一个数组,用Vector容器装的,要求找到一个临时最高点,可以假设有num[-1]和num[n]两个元素,都是无穷小,那么当只有一个 ...
- LeetCode Find Peak Element
原题链接在这里:https://leetcode.com/problems/find-peak-element/ 题目: A peak element is an element that is gr ...
- LeetCode Find Peak Element [TBD]
说要写成对数时间复杂度,算了想不出来,写个O(n)的水了 class Solution { public: int findPeakElement(const vector<int> &a ...
- LeetCode: Find Peak Element 解题报告
Find Peak Element A peak element is an element that is greater than its neighbors. Given an input ar ...
- [LeetCode] Find Peak Element 二分搜索
A peak element is an element that is greater than its neighbors. Given an input array where num[i] ≠ ...
- ✡ leetcode 169. Majority Element 求出现次数最多的数 --------- java
Given an array of size n, find the majority element. The majority element is the element that appear ...
- leetcode——169 Majority Element(数组中出现次数过半的元素)
Given an array of size n, find the majority element. The majority element is the element that appear ...
- Lintcode: Find Peak Element
There is an integer array which has the following features: * The numbers in adjacent positions are ...
随机推荐
- vue.mixin与vue.extend
vue.mixin 全局注册一个混合,影响注册之后所有创建的每个 Vue 实例.谨慎使用全局混合对象,因为会影响到每个单独创建的 Vue 实例(包括第三方模板).大多数情况下,只应当应用于自定义选项, ...
- 创建虚拟目录失败,必须为服务器名称指定“localhost”?看进来!!
没废话,直接讲! 关于微信开发过程,远程调试后,再次打开vs出现项目加载失败的解决办法! 上图: 这图应该不陌生,你肯定打开iis把绑定的域名给干掉了.这个提示很坑人,简直就是坑爹!!!fck!! 来 ...
- 理解ThreadLocal —— 一个map的key
作用: 当工作于多线程中的对象使用ThreadLocal维护变量时,threadLocal为每个使用该变量的线程分配一个独立的变量副本. 接口方法: protected T initialValue( ...
- 智能指针unique_ptr的用法
unique_ptr是独占型的智能指针,它不允许其他的智能指针共享其内部的指针,不允许通过赋值将一个unique_ptr赋值给另一个unique_ptr,如下面错误用法: std::unique_pt ...
- mysql技术点1.-----------查询当天的所有数据
select xs.* from xn_supervision xs where xs.task_type="+taskType+" and xs.create_time&g ...
- 关于MySql的1045错误修正
很多情况数据库很久没有使用,偶尔打开会出现一系列错误,例如1045错误即是 mysql ERROR 1045 : Access denied for user‘root’@localhost(usin ...
- 在xcode中用 swift 进行网络服务请求
xcode集成开发环境是运行于Mac苹果电脑上用于开发swift应用程序的工具,利用xcode可以很方便.直观的开发OS X和iOS系统所支持的应用程序. 1 开发环境: Mac OS 10.11 X ...
- prompt() 方法,弹框带输入框
prompt() 有alert的风格,却带着输入框,这是怎么实现的呢? 语法 prompt(text,defaultText) 参数 描述 text 可选.要在对话框中显示的纯文本(而不是 HTML ...
- SQL基础教程--实现增删查改功能(W3School)
1.SQL DML 和 DDL 可以把 SQL 分为两个部分:数据操作语言 (DML) 和 数据定义语言 (DDL). SQL (结构化查询语言)是用于执行查询的语法.但是 SQL 语言也包含用于更新 ...
- 利用Sharding-Jdbc实现分表
你们团队使用SpringMVC+Spring+JPA框架,快速开发了一个NB的系统,上线后客户订单跟雪花一样纷沓而来. 慢慢地,你的心情开始变差,因为客户和产品的抱怨越来越频繁,抱怨的最多的一个问题就 ...