題目
符合下列屬性的數組 arr 稱為 山脈數組 :
arr.length >= 3
存在 i(0 < i < arr.length - 1)使得:
-
arr[0] < arr[1] < … arr[i-1] < arr[i]
-
arr[i] > arr[i+1] > … > arr[arr.length - 1]
給你由整數組成的山脈數組 arr ,返回任何滿足 arr[0] < arr[1] < … arr[i - 1] < arr[i] > arr[i + 1] > … > arr[arr.length - 1] 的下標 i 。 -
示例 1:
輸入:arr = [0,1,0]
輸出:1
- 示例 2:
輸入:arr = [0,2,1,0]
輸出:1
- 示例 3:
輸入:arr = [0,10,5,2]
輸出:1
- 示例 4:
輸入:arr = [3,4,5,1]
輸出:2
- 示例 5:
輸入:arr = [24,69,100,99,79,78,67,36,26,19]
輸出:2
提示:
- 3 <= arr.length <= 104
- 0 <= arr[i] <= 106
一次遍歷
找出第一個遞減的轉折點,該轉折點的前一個下標即為山峰
代碼
class Solution {public int peakIndexInMountainArray(int[] arr) {for (int i=1;i<arr.length;i++){if(arr[i]<arr[i-1])return i-1;}return -1;}
}
二分法
利用題目發現如下性質:由于 arr 數值各不相同,因此峰頂元素左側必然滿足嚴格單調遞增,峰頂元素右側必然不滿足。
該數組是山峰數組,可以將頂點的左右兩側分為上坡和下坡,上坡是遞增數組,下坡是遞減數組,因此可以以下條件進行二分查找,
- 如果arr[mid]>arr[mid-1]說明當前區間[l,mid]都是遞增數組,因此頂點只會出現在[mid+1,r]區間,
- 如果arr[mid]<arr[mid-1]說明當前區間[mid,r]都是遞減數組,因此頂點只會出現在[l,mid-1]區間,
代碼
class Solution {public int peakIndexInMountainArray(int[] arr) {int l=1,r=arr.length-2;while (l<=r){int mid=(r-l)/2+l;if(arr[mid]>arr[mid-1])l=mid+1;else r=mid-1;}return r;}
}