問題:數組
A peak element is an element that is greater than its neighbors.spa
Given an input array where num[i] ≠ num[i+1]
, find a peak element and return its index.code
The array may contain multiple peaks, in that case return the index to any one of the peaks is fine.ip
You may imagine that num[-1] = num[n] = -∞
.element
For example, in array [1, 2, 3, 1]
, 3 is a peak element and your function should return the index number 2.input
Note:it
Your solution should be in logarithmic complexity.io
解決:function
① 自左至右遍歷數組,若是某元素比它左邊和右邊的元素大,則該元素必爲頂點。返回找到的第一個頂點便可。class
class Solution { //1ms
public int findPeakElement(int[] nums) {
if (nums == null || 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;
}
}
② 這種找Peak Element的首先想到的是binary search, 由於有更優的時間複雜度,不然brute force O(n)
的方法太直接了。
這個方法利用了題目中的以下性質:
1)最左邊的元素,它「更左邊」的元素比它小(負無窮),咱們認爲它是一個增加的方向
2)最右邊的元素,它「更右邊」的元素比它小(也是負無窮),咱們認爲它是一個降低的方向
根據這兩點咱們能夠判斷:最左邊和最右邊的元素圍成的區域內,必有至少一個頂點
如今咱們找到中點 nums[mid],將它與 nums[mid + 1] 做比較,若是前者較小,則方向是增加,與最左邊的元素是一致的,就把左邊界挪到mid+1的位置;不然與最右邊的元素一致,將右邊界挪到mid的位置。
這個方法的原理就是當左邊界方向爲「增加」,右邊界方向爲「降低」時,兩者圍出的區域必有一個頂點。
binary search的方法就是比較當前element與鄰居,至於左鄰居仍是右鄰居均可以,只要一致就行。不斷縮小範圍,最後鎖定peak element.time: O(logn), space: O(1).
class Solution {//0ms public int findPeakElement(int[] nums) { int left = 0; int right = nums.length - 1; while(left < right){ int mid = (right - left) / 2 + left; if (nums[mid] < nums[mid + 1]){ left = mid + 1; }else{ right = mid; } } return left; } }