題目及鏈接如下:
162. 尋找峰值
難度中等342收藏分享切換為英文接收動態(tài)反饋
峰值元素是指其值大于左右相鄰值的元素。
給定一個輸入數(shù)組 nums
,其中 nums[i] ≠ nums[i+1]
碗旅,找到峰值元素并返回其索引育勺。
數(shù)組可能包含多個峰值众眨,在這種情況下留荔,返回任何一個峰值所在位置即可晌端。
你可以假設(shè) nums[-1] = nums[n] = -∞
。
示例 1:
輸入: nums = [1,2,3,1]
輸出: 2
解釋: 3 是峰值元素丧鸯,你的函數(shù)應(yīng)該返回其索引 2。
示例 2:
輸入: nums = [1,2,1,3,5,6,4]
輸出: 1 或 5
解釋: 你的函數(shù)可以返回索引 1嫩絮,其峰值元素為 2丛肢;
或者返回索引 5, 其峰值元素為 6剿干。
說明:
你的解法應(yīng)該是 O(logN) 時間復(fù)雜度的蜂怎。
分析:當(dāng)時看到O(log N)就想到了用二分查找,但這是種投機(jī)取巧且不嚴(yán)謹(jǐn)?shù)慕忸}方法??置尔。如果按照題意分析的話杠步,這道題是一個求極大值的題目。我們高中的時候榜轿,在求解函數(shù)極值的方法中幽歼,其實(shí)就有用二分法求解極值的方法(忘了的話可以百度搜索二分法求極值)。因此這道題可以很自然地想到利用二分法來進(jìn)行求解差导。這道題便可以看成是用二分求解離散的極大值试躏。
代碼及細(xì)節(jié)分析如下:
class Solution {
public:
int findPeakElement(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
while (left < right) {//當(dāng)需要保留查找值與右鄰的關(guān)系時,采用leetcode二分專題的模板2
int mid = left +(right - left) / 2;//防止越界
if (nums[mid] > nums[mid + 1]) {
right = mid; //保證當(dāng)前right索引對應(yīng)的值大于右側(cè)鄰居的值
} else { // nums[mid] < nums[mid+1]
left = mid + 1; //保證當(dāng)前l(fā)eft索引對應(yīng)的值大于左側(cè)鄰居的值
}
//當(dāng)left和right重合時设褐,保證了當(dāng)前對應(yīng)的值既比左鄰大又比友鄰大颠蕴,即極值
}
return left;
}
};