一、题目名称java
Find Peak Element(寻找一个数组内的顶点)数组
二、题目地址code
https://leetcode.com/problems/find-peak-element/递归
三、题目内容索引
英文:ip
A peak element is an element that is greater than its neighbors.element
Given an input array where num[i] ≠ num[i+1], find a peak element and return its index.leetcode
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] = -∞.get
中文:
在一个数组内,若是某元素比它左右两个元素都大,则称该元素为一个“顶点”。现给出一个相邻元素必定不相同的数组,找出一个顶点元素并返回它的索引。一个数组中可能包含多个顶点,在这种状况下返回任意一个顶点的坐标便可。你能够假定第-1个元素和第n个元素是负无穷(这句话的意思就是最左边的元素假定它“再左边”还有一个比它小的元素,最右边的元素同理)。
例如:给定数组 [1, 2, 3, 1],则元素3是一个顶点,应返回它的索引值2
四、解题方法1
最容易想到的办法天然是自左至右遍历数组,若是某元素比它左边和右边的元素大,则该元素必为顶点。返回找到的第一个顶点便可。
Java代码以下:
/** * @功能说明:LeetCode 162 - Find Peak Element * @开发人员:Tsybius2014 * @开发时间:2015年11月4日 */ public class Solution { /** * 寻找顶点 * @param nums * @return */ public int findPeakElement(int[] nums) { if (nums == null) { return -1; } else if (nums.length == 0) { return -1; } else if (nums.length == 1) { return 0; } else if (nums[0] > nums[1]) { return 0; } else if (nums[nums.length - 1] > nums[nums.length - 2]) { return nums.length - 1; } for (int i = 1; i < nums.length - 1; i++) { if (nums[i - 1] <= nums[i] && nums[i + 1] <= nums[i]) { return i; } } return -1; } }
四、解题方法2
另外一种方法是使用二分查找法解决问题。这个方法利用了题目中的以下性质:
1)最左边的元素,它“更左边”的元素比它小(负无穷),咱们认为它是一个增加的方向
2)最右边的元素,它“更右边”的元素比它小(也是负无穷),咱们认为它是一个降低的方向
根据这两点咱们能够判断:最左边和最右边的元素围成的区域内,必有至少一个顶点
如今咱们找到中点 nums[mid],将它与 nums[mid + 1] 做比较,若是前者较小,则方向是增加,与最左边的元素是一致的,就把左边界挪到mid+1的位置;不然与最右边的元素一致,将右边界挪到mid的位置。
这个方法的原理就是当左边界方向为“增加”,右边界方向为“降低”时,两者围出的区域必有一个顶点。咱们能够写出以下Java代码实现此方法:
/** * @功能说明:LeetCode 162 - Find Peak Element * @开发人员:Tsybius2014 * @开发时间:2015年11月4日 */ public class Solution { /** * 寻找顶点 * @param nums * @return */ public int findPeakElement(int[] nums) { if (nums == null) { return -1; } else if (nums.length == 0) { return -1; } else if (nums.length == 1) { return 0; } int left = 0; int mid = 0; int right = nums.length - 1; while (left < right) { mid = left + (right - left) / 2; if (nums[mid] < nums[mid + 1]) { left = mid + 1; } else { right = mid; } } return left; } }
本题也可使用递归的方式进行二分搜索。
END