LeetCode 162 Find Peak Element

179 阅读1分钟

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;
    }
};