Leetcode 162 Find Peak Element 查找峰值元素(极大值)
来源:互联网 发布:卓智网络是国企 编辑:程序博客网 时间:2024/06/06 08:39
原题地址
https://leetcode.com/problems/find-peak-element/
题目描述
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.
给出一个不含重复元素的数组num
,找出其中的峰值元素并返回其索引(下标)值.
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] = -∞
.
假设nums[-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
.
例如,在数组 [1, 2, 3, 1]
中,3
是峰值元素,你的函数需要返回下标2
.
spoilers.
挑战.
Note:
注意:
Your solution should be in logarithmic complexity.
你的方法的时间复杂度需要为对数级别复杂度.
解题思路一 O(n) 比较次数2n
非常暴力的解决方法,我们遍历所有元素,判断其是否大于前后的元素即可.
代码一
int findPeakElement(int* nums, int numsSize) { if (numsSize == 1) return 0; if (*nums > *(nums + 1)) return 0; int i = 1; for (; i < numsSize - 1; ++i) { if (*(nums + i) > *(nums + i - 1) && *(nums + i) > *(nums + i + 1)) return i; } return numsSize - 1;}
完整代码https://github.com/Orange1991/leetcode/blob/master/162/c/main.c
解题思路二 O(n) 比较次数n
对于上述解法,我们发现有一个可以改进的地方:
- 对于第0个元素,nums[0] > nums[-1]是一定成立的,因此如果nums[0] > nums[1]则返回0
- 如果nums[0] < nums[1],那么对于第1个元素,判断式中的nums[i] > nums[i-1]是显然成立的.实际上这个判断在上一次循环中已经判断过了,程序执行到i=1就已经说明nums[1] > nums[0]了,同理,如果执行到i=2,必有nums[2] > nums[1].因此,在i之前的所有元素是递增的,我们在每次判断时只需要其是否大于后面的元素即可.这样比较次数可以减少到n次.
算法
- 我们从0开始往后遍历元素,如果某个元素大于其后面的元素,则该元素就是峰值元素.
- 对于最差情况,数组是一个递增的数组,我们遍历到数组末尾,此时由于nums[n]=-∞,所以nums[n-1]>nums[n]且nums[n-1]>nums[n-2],因此最后一个元素就是峰值元素.
代码二
int findPeakElement(int* nums, int numsSize) { int i = 0; for (; i < numsSize - 1; ++i) if (*(nums + i) > *(nums + i + 1)) return i; return numsSize - 1;}
完整代码https://github.com/Orange1991/leetcode/blob/master/162/c/solution2.c
解题思路三 O(logn)
在解法二中,我们可以发现两个规律,一个是一定存在峰值元素,另一个是在遍历查找过程中对于某个元素之前的所有元素是递增的.其实这两个描述并不准确.我尝试用如下语句来描述这个规律:
- 规律一:如果nums[i] > nums[i+1],则在i之前一定存在峰值元素
- 规律二:如果nums[i] < nums[i+1],则在i+1之后一定存在峰值元素
我们可以采用二分查找的方式设计如下算法:
算法
- front设为首元素,back设为尾元素
- 如果front==end,返回front
- 取中间元素center,判定其是否比后面的元素大,是则4,否则5
- back=center,跳到1
- front=center+1,跳到1
代码三
int findPeakElement(int* nums, int numsSize) { int front = 0, back = numsSize - 1, center; while (front <= back) { if (front == back) return front; center = (front + back) / 2; if (*(nums + center) < *(nums + center + 1)) front = center + 1; else back = center; }}
完整代码https://github.com/Orange1991/leetcode/blob/master/162/c/solution3.c
2015/8/3
- Leetcode 162 Find Peak Element 查找峰值元素(极大值)
- LeetCode 162. Find Peak Element(查找峰值)
- LintCode Find Peak Element(查找峰值)
- LeetCode OJ 之 Find Peak Element (查找极大元素)
- LintCode Find Peak Element II(查找峰值II)
- 【LeetCode】162.Find Peak Element 寻找峰值(二分法)
- leetcode 162. Find Peak Element-查找峰元素|二分查找
- [C++]LeetCode: 118 Find Peak Element (二分查找 寻找数组局部峰值)
- Find Peak Element-找出峰值元素w问题描述
- [leetcode-162]Find Peak Element(c)
- LeetCode(162) Find Peak Element
- Leetcode 162 - Find Peak Element(二分)
- LeetCode(162) Find Peak Element
- [leetcode 162] Find Peak Element
- leetcode-162 Find Peak Element
- [LeetCode 162]Find Peak Element
- LeetCode 162 Find Peak Element
- [leetcode] #162 Find Peak Element
- volley学习笔记(六):volley框架下发送和读取cookie
- 计算机英语学习(二)
- Google C++ Coding Style:右值引用(Rvalue Reference)
- JDOM解析XML
- Lubuntu 12.04开机启动应用程序脚本
- Leetcode 162 Find Peak Element 查找峰值元素(极大值)
- HDU - 2883 kebab (最大流)
- 封装类中实现另外两个Activity之间的跳转
- c++线程池
- c++编译链接
- CSDN的Markdown编辑器如何添加空格
- android Graphics(一):概述及基本几何图形绘制
- Android知识体系结构
- c++编译链接过程