[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 ...
随机推荐
- JavaScript 垃圾回收
在公司经常会听到大牛们讨论时说道内存泄露神马的,每每都惊羡不已,最近精力主要用在了Web 开发上,读了一下<JavaScript高级程序设计>(书名很唬人,实际作者写的特别好,由浅入深)了 ...
- unity3d 免费好用的数据库处理框架 数据库直连框架
一.概述 前不久有一个哥们做PC游戏开发的.使用到Unity3d, 正好找到我. 我给他提供了Unity3d如何Moon.Orm来智能化编程的方式. 我们先看看怎么更加便捷sqlite. http:/ ...
- Docker 基础 : 数据管理
用户在使用 Docker 的过程中,往往需要能查看容器内应用产生的数据,或者需要把容器内的数据进行备份,甚至多个容器之间进行数据的共享,这必然涉及容器的数据管理操作.容器中管理数据主要有两种方式:数据 ...
- linux终端指令总结
一直没机会进行linux指令的系统学习,但是工作中总能遇到通过指令操作文件或数据库的情况,总不能一味地依赖后端开发者的帮忙.上任领导说过,要是在同一个地方跌倒,那么你就是傻子.我可不想成为傻子,so, ...
- 基于STM32Cube的脉冲输出
方法一:定时器定时I/O反转生成脉冲波形 1.建立STM32Cube选择STM32F429,我使用的STM32F429-discovery开发板,晶振是8MHz,时钟配置为180M,这样定时器内部时钟 ...
- Basic Tutorials of Redis(8) -Transaction
Data play an important part in our project,how can we ensure correctness of the data and prevent the ...
- mvc过滤器学习(1)
mvc 过滤器结构图 AuthorizeAttribute AuthorizeAttribute是IAuthorizationFilter的默认实现,添加了Authorize特性的Action将对用户 ...
- Android Time类 奇葩的设定
Android 的Time.MONTH默认是0-11表示1-12月,小白表示坑爹啊,浪费多少精力啊.
- 在Word中输入数学公式
office官方说明:https://support.office.com/en-us/article/Linear-format-equations-and-Math-AutoCorrect-in- ...
- chunkupload文件上传断点续传组件(java)
chunkupload简介 chunkupload是一款基于java语言的断点续传组件,针对文件上传,非文件下载,集成方便,使用简单. 从整体上讲,chunkupload会对文件进行切片处理,每个切片 ...