Leetcode 题解(每日打卡)
[162.寻找峰值]
题目描述
峰值元素是指其值严格大于左右相邻值的元素。
给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞ 。
你必须实现时间复杂度为 O(log n) 的算法来解决此问题。
示例1:
输入:nums = [1,2,3,1]
输出:2
解释:3 是峰值元素,你的函数应该返回其索引 2。
示例2:
输入:nums = [1,2,1,3,5,6,4]
输出:1 或 5
解释:你的函数可以返回索引 1,其峰值元素为 2;
或者返回索引 5, 其峰值元素为 6。
思路
这道题目给的要求是要求时间复杂度为O(log n),很容易想到使用二分法对其进行求解,但是与常见的二分法不一样的是,这次二分法是一个无序数组,我们不能对其先进行排序,再进行二分搜索,我们只能对这个无序的数组进行二分搜索,但是我们由题目可以观察得出我们的目标值永远在边界内,只要我们不断的压缩我们的搜索空间,我们就可以找到那个目标值。
本题的目标是寻找峰值那么我们也可以利用二分法的思想,并且每次都往相邻两值中,相对较大的那个值所在的范围进行搜索,这就有点像我们在爬坡一样,只要我们向上走,我们总能找到一个峰顶。
代码实现
class Solution {
public:
int findPeakElement(vector<int>& nums) {
int left = 0;
int right = nums.size()-1;
int mid = (left+right)/2;
while(true){
if(mid == 0){
if(right - left == 1){
return nums[left]-nums[right]>0?left:right;
}else{
return 0;
}
}
if(mid == nums.size()-1) return nums.size()-1;
if(nums[mid]-nums[mid-1] > 0 && nums[mid]-nums[mid+1] > 0){
return mid;
}else{
if(nums[mid]-nums[mid-1] <= 0){
right = mid - 1;
mid = (left+right)/2;
}else if(nums[mid]-nums[mid+1] <= 0){
left = mid + 1;
mid = (left+right)/2;
}
}
}
return 0;
}
};
时间复杂度: O(log n)
空间复杂度: O(1)