【LeetCode 162】寻找峰值

题目描述

原题链接: LeetCode.162 寻找峰值

解题思路

  • 数组相邻元素不相等, 峰值可能有多个, 整个数组的最大值肯定是峰值之一, 直接遍历数组获取最大值也能得到答案;
  • 但是写明复杂度要求O(log n)就是否定了最简单的O(n)遍历解法, 需要用二分法;
  • 按照题意数组边界另一端等同于无穷小, 可以直接分别按照首尾两个数字大小来判断首尾是否是峰值;
  • 如果首尾不是峰值, 说明在首位数组值是上升, 末尾数组是下降的趋势, 必然在中间某个位置至少存在一个峰值将元素趋势从上升变为下降;
  • 考虑连续三个元素的大小关系来判断峰值:
    1. nums[i - 1] < nums[i] > nums[i + 1], i就是峰值;
    2. nums[i - 1] < nums[i] < nums[i + 1], i位置仍然处于上升趋势, 要在大于i的右边区域继续查找;
    3. nums[i - 1] > nums[i] > nums[i + 1], i位置处于下降趋势, 在小于i的左边区域可以找到峰值;
    4. nums[i - 1] > nums[i] < nums[i + 1], i是谷底值, 左右两边区域都存在峰值;
  • 总结4种情况, nums[i] > nums[i + 1]时峰值可能是i本身或者要继续在[0, i-1]范围内找, nums[i] < nums[i + 1]时峰值都可以在[i + 1, n - 1]范围找到, 这就确定了二分逻辑;

解题代码

  • 个人倾向于使用的便于理解的写法:

      /**
       * 朴素好读懂的二分解法
       * 执行用时: 0 ms , 在所有 Java 提交中击败了 100.00% 的用户
       * 内存消耗: 41.24 MB , 在所有 Java 提交中击败了 83.37% 的用户
       * 编辑日期: 2024-05-10
       */
      public int findPeakElement(int[] nums) {
          if (nums.length == 1 || nums[1] < nums[0]) {
              return 0;
          }
          int right = nums.length - 1;
          if (nums[right - 1] < nums[right]) {
              return right;
          }
          int left = 0, ans = 0;
          while (left <= right) {
              int mid = left + ((right - left) >> 1);
              if (nums[mid] > nums[mid + 1]) {
                  right = mid - 1;
                  ans = mid;
              }
              else {
                  left = mid + 1;
              }
          }
          return ans;
      }
    
  • 更简洁的写法, 不熟悉的人看到可能要举几个例子才好理解:

      /**
       * 更简洁代码版本, 去除了边界判断和辅助变量ans
       * 执行用时: 0 ms , 在所有 Java 提交中击败了 100.00% 的用户
       * 内存消耗: 40.04 MB , 在所有 Java 提交中击败了 100.00% 的用户
       */
      public int findPeakElement(int[] nums) {
          int left = 0, right = nums.length - 1;
          while (left < right) {
              int mid = left + ((right - left) >> 1);
              if (nums[mid] < nums[mid + 1]) {
                  left = mid + 1;
              }
              else {
                  right = mid;
              }
          }
          return left;
      }
    

posted on 2024-05-11 17:52  真不如烂笔头  阅读(42)  评论(0编辑  收藏  举报

导航