162. 寻找峰值

102 阅读1分钟

方法一: 二分, TC O(logN)

  • 每次二分后,mid可能落在一个上升区间或者下降区间,下一次查找的范围应为较大的那一段。
    • 较大的那一段在某个元素下降,那么可以确定峰值。
    • 较大的那一段持续递增,那么峰值就在端点处,因为两端以外是负无穷。
  • 关键在于处理好越界。

写法2

class Solution {
    public int findPeakElement(int[] nums) {
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            // 只剩一个数
            if (left == right) {
                return left;
            }
            // 1.防止越界 2.处理只剩两个数的情况 e.g. 56
            if (right - left == 1) {
                return nums[left] > nums[right] ? left : right;
            }
            if (nums[mid] > nums[mid - 1] && nums[mid] > nums[mid + 1]) {
                return mid;
            } else if (nums[mid + 1] > nums[mid]) {// 312,写成mid > mid - 1会死循环
                left = mid + 1;
            } else if (nums[mid - 1] > nums[mid]) {// 312,写成mid > mid - 1会死循环
                right = mid - 1;
            }
        }
        return 0;
    }
}

写法1

class Solution {
    public int findPeakElement(int[] nums) {
        int low = 0, high = nums.length - 1;
        while (low < high) {//<能防止mid+1越界
            int mid = low + (high - low) / 2;
            if (nums[mid] > nums[mid + 1]) {//不写mid- 1是因为mid-1可能越界,因为mid是向下取整的。
                high = mid;
            } else {
                low = mid + 1;
            }
        }
        return low;

    }
}

方法二:遍历一遍,找最大值, O(N)