LeetCode 162 Find Peak Element
思路
此题思路很明显就是通过二分超着缩小搜索范围。本题采用左闭右闭区间,即[left, right]。mid1为区间中点,mid2为mid1+1。然后比较mid1指向的元素和mid2指向的元素。如果mid1指向的元素较大,说明结果在[left, mid1]。如果mid2指向的元素较大,说明结果在[mid2, right]。
关于越界情况的讨论:一开始检查输入数组的大小是否为1,如果为1,直接返回0。如果大于1,不用担心出现越界。因为本题采用的是左闭右闭区间,mid1往往是靠近left的,所以mid1是不会越界的。mid2为mid1 + 1,如果mid2要越界,那么只有当mid1为nums.size() - 1时才有可能。而只有当left等于right等于nums.size() - 1时,mid1才可能为nums.size() - 1。而循环的条件是left < right。因此left等于right的情况不可能出现。因此mid2不可能出现越界的情况。
代码
递归
class Solution {
public:
int findPeakElement(vector<int>& nums) {
if (nums.size() == 1) return 0;
return findPeak(nums, 0, nums.size() - 1);
}
int findPeak(vector<int> &nums, int left, int right) {
if (left == right) return left;
int mid1 = left + (right - left) / 2, mid2 = mid1 + 1;
if (nums[mid1] > nums[mid2])
return findPeak(nums, left, mid1);
else
return findPeak(nums, mid2, right);
}
};
迭代
class Solution {
public:
int findPeakElement(vector<int>& nums) {
if (nums.size() == 1) return 0;
int left = 0, right = nums.size() - 1, mid1, mid2;
while (left < right) {
mid1 = left + (right - left) / 2;
mid2 = mid1 + 1;
if (nums[mid1] > nums[mid2])
right = mid1;
else left = mid2;
}
return left;
}
};