博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
162. Find Peak Element
阅读量:7116 次
发布时间:2019-06-28

本文共 4177 字,大约阅读时间需要 13 分钟。

题目:

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.

链接: 

题解:

找1D-Peak,正好是MIT 6.006第一课的第一个问题。使用Binary Search,当nums[mid] < nums[mid + 1],nums[mid + 1]可能为peak,设置lo = mid + 1, else设置hi = mid。当lo == hi时,找到peak。 

Time Complexity - O(logn), Space Compleixty - O(1)。

public class Solution {    public int findPeakElement(int[] nums) {            //MIT 6.006 Introduction to Algorithms        if(nums == null || nums.length == 0)            // watch the 2d version            return 0;        int lo = 0, hi = nums.length - 1;                while(lo <= hi) {            if(lo == hi)                return lo;            int mid = lo + (hi - lo) / 2;            if(nums[mid] < nums[mid + 1])                lo = mid + 1;            else                hi = mid;        }                return -1;    }}

 

Python:

class Solution(object):    def findPeakElement(self, nums):        """        :type nums: List[int]        :rtype: int        """        if not nums:            return -1        lo = 0        hi = len(nums) - 1                while lo <= hi:            if lo == hi:                return lo            mid = lo + (hi - lo) / 2            if nums[mid] < nums[mid + 1]:                lo = mid + 1            else:                hi = mid                        return -1

 

Follow up是找2D-Peak,这时候要用Divide-and-Conquer,在一个类似window的方框(first,mid,last row and column)里遍历所有元素。找不到的话,在window所有元素中的最大元素的neighbor里,找到一个比这个元素大的neighbor,然后在这个neighbor所在的 (n/2 x n/2)的小window里找,这次查找包括之前的边框,之后recursively。 详细的方法还要继续看mit的slides,Time Complexity是O(n)。

 

二刷:

此题在Microsoft Excel组onsite时第一轮第一题考到了,还问到了follow up。发现自己了解得并不是很深刻。下面记录一下重新思考后的写法,写得比较sloppy。 三刷的时候要进行化简。

题目给定了一个数组,要求在数组中找到一个peak。以前在Youtube MIT的视频里看到过,所以知道有几种方法可以做到。我们不考虑题目给定的nums[i] != nums[i - 1]的条件,对于general case来说, 假如index i在的nums[i]是一个peak,那么一定有 nums[i] >= nums[i - 1] 并且nums[i] >= nums[i + 1]。 

  1. 顺序查找,从1到 len - 2里顺序比较nums[i] >= nums[i - 1] && nums[i] >= nums[i + 1]
  2. 找到global最大值,global最大值也是一个peak
  3. binary search。我们每次查找一个中间mid, 将mid和它左右两边的元素进行比较,假如mid是peak,那么我们直接返回。否则假如nums[mid] < nums[mid - 1],从mid向队首肯定有一个上升序列,我们在左半边继续查找, 否则nums[mid] < nums[mid + 1], 从mid向队尾肯定有一个上升序列,我们在右半边继续查找。最后return lo或者hi都可以。 在查找之前也要处理一下边界问题。边界问题的精简还需要好好思考,再多写一写。最后也要考虑一些test case,自己测试一下。

Java:

Binary Search:

Time Complexity - O(logn), Space Compleixty - O(1)。

public class Solution {    public int findPeakElement(int[] nums) {        if (nums == null || nums.length < 2) {            return 0;        }        if (nums[0] >= nums[1]) {            return 0;        }        int len = nums.length;        if (nums[len - 1] >= nums[len - 2]) {            return len - 1;        }        int lo = 1, hi = len - 2;        while (lo < hi) {            int mid = lo + (hi - lo) / 2;            if (nums[mid] >= nums[mid - 1] && nums[mid] >= nums[mid + 1]) {                return mid;            } else if (nums[mid] < nums[mid - 1]) {                hi = mid - 1;            } else {                lo = mid + 1;            }        }        return lo;    }}

 

Update:

上面的代码过长,还是可以简化到一刷的代码。

public class Solution {    public int findPeakElement(int[] nums) {        if (nums == null || nums.length < 2) return 0;        int lo = 0, hi = nums.length - 1;                while (lo <= hi) {            if (lo == hi) return lo;            int mid = lo + (hi - lo) / 2;            if (nums[mid] < nums[mid + 1]) {                lo = mid + 1;            } else {                hi = mid;            }        }        return lo;    }}

 

Test Case:

1.  [1, 3, 4, 2, 4, 3, 1]

 

Reference:

http://stellar.mit.edu/S/course/6/fa13/6.006/materials.html

https://docs.python.org/2/tutorial/

http://stellar.mit.edu/S/course/6/fa13/6.006/courseMaterial/topics/topic6/lectureNotes/L01_-_Peak_Finding/L01_-_Peak_Finding.pdf

http://stellar.mit.edu/S/course/6/fa13/6.006/courseMaterial/topics/topic4/lectureNotes/rec01_intro/rec01_intro.pdf

转载地址:http://gzwel.baihongyu.com/

你可能感兴趣的文章
我的友情链接
查看>>
Spark Graphx编程指南
查看>>
配置tomcat
查看>>
kernel: TCP: time wait bucket table overflow错误的解决办法
查看>>
python3 打印99乘法表
查看>>
Linux命令总结-2
查看>>
基于glusterfs和gearman的离线任务运算分布式化方案介绍
查看>>
小学生信息技术课的有效教学
查看>>
天堂与地狱的区别
查看>>
java io小实例
查看>>
127小时
查看>>
Windows Server 2008 R2 SP1中的具体改进
查看>>
安装Discuz论坛系统
查看>>
信息系统上线时的准备
查看>>
(转)cocos2d-x2.0.3创建android程序缺失java文件的问题
查看>>
我的友情链接
查看>>
基于Metronic的Bootstrap开发框架经验总结(3)--下拉列表Select2插件的使用
查看>>
查看 MySQL 数据库中每个表占用的空间大小
查看>>
Linux登陆图形,佛祖保佑
查看>>
海洋迅雷VIP帐号获取器
查看>>