题目描述
给定一个数组,数组数字先递增再递减,找到那个峰值的位置。数组由切仅有一个峰值
可能的corner case
- 数字是非严格单调递增递减,可能有重复值
- 峰值可能在开头或者结尾
题目思路
使用二分查找,基于题目的数组性质,找峰值点有明确二分关系,如果当前数比前面的数大那么处于上升区,分值可能是当前点或者后面的点;如果当前数小于等于前一个数那么处于下降区,峰值点一定在这个数前面。所以我们这道题目是要找到当前数字大于前一个数的最后一个位置。
代码如下
- 找到当前数字大于前一个数的最后一个位置即为最后解
class Solution {
public:
int peakIndexInMountainArray(vector<int>& arr) {
int l = 0, r = arr.size()-1;
while (l < r) {
int mid = l + (r-l+1>>1); // 这里+1为了防止死循环
if (arr[mid]>arr[mid-1]) l = mid;
else r = mid-1;
}
return l;
}
};
- 找到当前数字小于前一个数的第一个位置这个位置前一个数即为解
class Solution {
public:
int peakIndexInMountainArray(vector<int>& arr) {
int l = 0, r = arr.size()-1;
//找到小于前面的第一个数,结果l-1;
while (l < r) {
int mid = l + (r-l>>1);
if (arr[mid]<arr[mid-1]) r = mid;
else l = mid+1;
}
return l-1;
}
};
时间复杂度:
O
(
l
o
g
N
)
O(logN)
O(logN)
空间复杂度:
O
(
1
)
O(1)
O(1)