首页 > 其他分享 >非有序数组也能二分? —— 红蓝染色法续篇(Leetcode 162.寻找峰值)

非有序数组也能二分? —— 红蓝染色法续篇(Leetcode 162.寻找峰值)

时间:2024-03-21 22:00:26浏览次数:187  
标签:峰顶 nums 元素 mid 峰值 数组 染色法 Leetcode 162

1. 写在前面

  本文为个人学习总结,参考:B站Up:灵茶山艾府

参考视频链接:https://www.bilibili.com/video/BV1QK411d76w/


2. 题目

  我们来看一下下面这道题:

峰值元素是指其值严格大于左右相邻值的元素。
给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回*任何一个峰值*所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞ 。
你必须实现时间复杂度为 O(log n) 的算法来解决此问题。

示例 1:
输入:nums = [1,2,3,1]
输出:2
解释:3 是峰值元素,你的函数应该返回其索引 2。

示例 2:
输入:nums = [1,2,1,3,5,6,4]
输出:1 或 5 
解释:你的函数可以返回索引 1,其峰值元素为 2;
     或者返回索引 5, 其峰值元素为 6。

3. 解法

  这有什么难的?遍历!嘿嘿,遍历的时间复杂度为O(n),题目要求时间复杂度为 O(log n),很经典的二分查找的时间复杂度。但是数组并不是有序呀,还能用二分吗?

  其实,二分查找的应用并不限制要求数组一定有序,只需要我们求解的目标满足二段性即可。我们在二分查找的时候,每次都会筛选掉一半的内容,而我们只要能找到一个分割点,将目标数组分割为两段内容,我们就可以运用二分的思想解决问题。

  峰值元素,指的是比相邻左边和相邻右边都大的元素,在数学层面我们可以理解为局部极大值。我们可以将寻找峰值元素的过程比喻成爬山,对于数组中的每一个元素,无非就三种状态:在上山,在峰顶,在下山,如果我们一直往高处走,我们可能会继续上山,或者到达峰顶;如果我们往低处走,我们是没有办法到达峰值元素的。也就是说,峰值一定会在值大的一侧,在我们寻找峰顶的过程中,我们都是尽量地往值大的方向去寻找峰顶。
  当我们比较nums[mid]和nums[mid+1]的关系后,我们就可以确定峰值会出现在哪一边了。
  我们可以看个图帮助理解一下:

  你可能会问:为什么一直往高处走肯定会到达峰顶呢?或者是,为什么峰值一定会在值大的一侧?我们需要注意到,题目中存在一个最最最最重要的前提
  假设 nums[-1] = nums[n] = -∞ 。
  也就是说,我们最坏的情况无非就是一直往高处走停不下来,直到走到数组末尾,假如数组为[1,2,3,4],其实它是:[-∞,1,2,3,4,-∞],在这种情况下,4比左右两边都要大,4就是峰顶。

  那么,我们是不是已经找到了二分法的分割点了呀。我们运用红蓝染色法,首先确定循环不变量,也就是红色区域和蓝色区域分别代表什么。我们规定:

    红色(左边部分):峰顶左侧的元素
    蓝色(右边部分):峰顶或者峰顶右侧的元素

  定义左指针 L = 0, 右指针R = nums.length - 2,左指针左侧区域为红色,右指针右侧区域为蓝色。
  为啥右指针R不指向nums的最后一位(R = nums.length - 1),因为数组的最后一位元素要么是峰顶,要么是峰顶右侧的元素,肯定为蓝色,所以可以从倒数第二位开始判断
题目中还有一个前提:
  对于所有有效的 i 都有 nums[i] != nums[i + 1]
  也就是说相邻元素肯定不相等,我们每次比较 nums[mid] 和 nums[mid+1] 的关系,如果:
① nums[mid] < nums[mid+1]
  右侧大,右侧肯定有峰值,我们移动 L 左指针至 mid+1 位置
② nums[mid] > nums[mid+1]
  左侧大,左侧肯定有峰值,我们移动 R 右指针至 mid-1 位置

  当二分查找结束,退出循环时,左指针 L 指向结果, 或者右指针的右一位 R+1 指向结果,返回哪个都行。

4. 代码(Java版本)

class Solution {
    public int findPeakElement(int[] nums) {
        int left = 0;
        int right = nums.length - 2;
        while(left<=right){
            int mid = (left + right) /2;
            if(nums[mid]<nums[mid+1]){
                left = mid + 1;
            }
            else{
                right = mid - 1;
            }
        }
        return left;
    }
}

标签:峰顶,nums,元素,mid,峰值,数组,染色法,Leetcode,162
From: https://www.cnblogs.com/Ineedyan/p/18088334

相关文章

  • leetcode 路经总和 pathsum
    很熟悉的一道题,XX二面做过,面试官没让我当场造树,让我用数组模拟树来运行,依旧跑出来了。但是刚刚再做了一下,没思路,不会写......
  • LeetCode 剑指Offer 练习
    目录题目整理来源:[https://zhuanlan.zhihu.com/p/112990684](LeetCodeByPython:剑指Offer第2版解题目录)数据结构[https://leetcode.cn/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/solutions/](LCR120.寻找文件副本)[https://leetcode.cn/problems/er-wei-......
  • LeetCode刷题记录——day3
    1、https://leetcode.cn/problems/gas-station/submissions/514930619/?envType=study-plan-v2&envId=top-interview-150对于这个问题可以这样来考虑,将数据看作一个环,如果答案唯一,那么就意味着从任意一个节点开始寻找,最后都会得到同一个节点的答案,那么为何不直接从0节点开始呢?其......
  • 记忆化搜索 —— Leetcode 2684. 矩阵中移动的最大次数
    题目如下:给你一个下标从 0 开始、大小为 mxn 的矩阵 grid ,矩阵由若干 正 整数组成。你可以从矩阵第一列中的 任一 单元格出发,按以下方式遍历 grid :从单元格 (row,col) 可以移动到 (row-1,col+1)、(row,col+1) 和 (row+1,col+1) 三个单元......
  • LeetCode-滑动窗口最大值
    """题目来源https://leetcode.cn/problems/sliding-window-maximum/"""fromcollectionsimportdequeclassSolution(object):defmaxSlidingWindow(self,nums,k):#记录所有区间长度为k的最大值ans=[]#单调递减队列,从队首......
  • 代码随想录算法训练营day29 | leetcode 491. 非递减子序列、46. 全排列、47. 全排列 I
    目录题目链接:491.非递减子序列-中等题目链接:46.全排列-中等题目链接:47.全排列II-中等题目链接:491.非递减子序列-中等题目描述:给你一个整数数组nums,找出并返回所有该数组中不同的递增子序列,递增子序列中至少有两个元素。你可以按任意顺序返回答案。数组中可能含有重......
  • LeetCode 2265. Count Nodes Equal to Average of Subtree
    原题链接在这里:https://leetcode.com/problems/count-nodes-equal-to-average-of-subtree/description/题目:Giventhe root ofabinarytree,return thenumberofnodeswherethevalueofthenodeisequaltothe average ofthevaluesinits subtree.Note:Th......
  • 2024-03-20 leetcode写题记录
    目录2024-03-20leetcode写题记录23.合并K个升序链表题目链接题意解法4.寻找两个正序数组的中位数题目链接题意解法25.K个一组翻转链表题目链接题意解法2024-03-20leetcode写题记录23.合并K个升序链表题目链接23.合并K个升序链表题意给你一个链表数组,每个链表......
  • 2024-03-19 leetcode写题记录
    目录2024-03-19leetcode写题记录85.最大矩形题目链接题意解法2024-03-19leetcode写题记录85.最大矩形题目链接85.最大矩形题意给定一个仅包含0和1、大小为rowsxcols的二维二进制矩阵,找出只包含1的最大矩形,并返回其面积。解法先对每个元素求出其往上能延伸......
  • LeetCode刷题记录——day2
    https://leetcode.cn/problems/product-of-array-except-self/description/?envType=study-plan-v2&envId=top-interview-150问题在于不使用除法并且空间复杂度为O(1),当第一次从头开始遍历时由于不知道后续数组元素是什么,所以无法得到答案,而如果当知道一个后续数组元素后,又回去更......