代码随想录算法训练营day59 | 503.下一个更大元素II,42. 接雨水

news2024/12/22 22:42:57

代码随想录算法训练营day59 | 503.下一个更大元素II,42. 接雨水

  • 503.下一个更大元素II
    • 解法一:单调栈(两次遍历解决环状问题)
  • 42. 接雨水
    • 解法一:单调栈(横向累计)
    • 解法二:暴力解法
    • 解法三:双指针优化
  • 总结


503.下一个更大元素II

教程视频:https://www.bilibili.com/video/BV15y4y1o7Dw
在这里插入图片描述

解法一:单调栈(两次遍历解决环状问题)

class Solution {
    public int[] nextGreaterElements(int[] nums) {
        int[] result = new int[nums.length];
        Arrays.fill(result, -1);
        Deque<Integer> stack = new LinkedList<>();
        stack.push(0);
        int n = nums.length;
        for(int i=1;i<2*n;i++){
            if(nums[i%n]<=nums[stack.peek()]){
                stack.push(i%n);
            }else{
                while(!stack.isEmpty() && nums[i%n]>nums[stack.peek()]){
                    result[stack.peek()]=nums[i%n];
                    stack.pop();
                }
                stack.push(i%n);
            }
        }
        return result;
    }
}

42. 接雨水

教程视频:https://www.bilibili.com/video/BV1uD4y1u75P
在这里插入图片描述

解法一:单调栈(横向累计)

找到左右第一个比当前元素高的值,选其中小的高督察乘以宽度得到当前雨水层的水。
在这里插入图片描述

class Solution {
    public int trap(int[] height) {
        Deque<Integer> stack = new LinkedList<>();
        stack.push(0);
        int result=0;
        for(int i=1;i<height.length;i++){
            if(height[i]<height[stack.peek()]){
                stack.push(i);
            }else if(height[i]==height[stack.peek()]){
                // 因为相等的相邻墙,左边一个是不可能存放雨水的,所以pop左边(前一个)index, push当前的index
                stack.pop();
                stack.push(i);
            }else{
                while(!stack.isEmpty() && height[i]>height[stack.peek()]){
                    int curIndex = stack.pop();
                    if(!stack.isEmpty()){//左侧遍历过的元素,大于当前值的最近元素就在栈口第二个位置
                        // System.out.println("right: "+i+", "+height[i]+", mid: "+curIndex+", "+height[curIndex]+", left: "+stack.peek()+", "+height[stack.peek()]);
                        int h = Math.min(height[i], height[stack.peek()])-height[curIndex];
                        int w = i-stack.peek()-1;
                        result+=h*w;
                    }
                }
                stack.push(i);
            }
        }
        return result;
    }
}

解法二:暴力解法

按照列来计算,比较容易理解。如果按照列来计算的话,宽度一定是1了,我们再把每一列的雨水的高度求出来就可以了。
在这里插入图片描述
可以看出每一列雨水的高度,取决该列 左侧最高的柱子右侧最高的柱子 中最矮的那个柱子的高度

首先从头遍历所有的列,并且要注意第一个柱子和最后一个柱子不接雨水。在for循环中求左右两边最高柱子。最后,计算该列的雨水高度。

因为每次遍历列的时候,还要向两边寻找最高的列,所以时间复杂度为O(n^2),空间复杂度为O(1)。
力扣上暴力解法超时了。

class Solution {
    public int trap(int[] height) {
        int result=0;
        for(int i=0;i<height.length;i++){
            if(i==0 || i==height.length-1){
                continue;
            }
            int leftMax = height[i];
            int rightMax = height[i];
            for(int j=i-1;j>=0;j--){
                if(height[j] > leftMax) leftMax = height[j];
            }
            for(int j=i+1;j<height.length;j++){
                if(height[j]>rightMax) rightMax =height[j];
            }
            if(leftMax!=0 && rightMax!=0){
                result+=Math.min(leftMax, rightMax)-height[i];
            }
        }
        return result;
    }
}

解法三:双指针优化

为了得到两边的最高高度,使用了双指针来遍历,每到一个柱子都向两边遍历一遍,这其实是有重复计算的。我们把每一个位置的左边最高高度记录在一个数组上(maxLeft),右边最高高度记录在一个数组上(maxRight),这样就避免了重复计算。

当前位置,左边的最高高度是前一个位置的左边最高高度和本高度的最大值。
从左向右遍历:maxLeft[i] = max(height[i], maxLeft[i - 1]);
从右向左遍历:maxRight[i] = max(height[i], maxRight[i + 1]);

class Solution {
    public int trap(int[] height) {
        int length = height.length;
        if (length <= 2) return 0;
        //记录左右诸子的最大高度,避免重复遍历
        int[] maxLeft = new int[length];
        int[] maxRight = new int[length];

        // 记录每个柱子左边柱子最大高度
        maxLeft[0] = height[0];
        for (int i = 1; i< length; i++) maxLeft[i] = Math.max(height[i], maxLeft[i-1]);

        // 记录每个柱子右边柱子最大高度
        maxRight[length - 1] = height[length - 1];
        for(int i = length - 2; i >= 0; i--) maxRight[i] = Math.max(height[i], maxRight[i+1]);

        // 求和
        int result = 0;
        for (int i = 0; i < length; i++) {
            int count = Math.min(maxLeft[i], maxRight[i]) - height[i];
            if (count > 0) result += count;
        }
        return result;
    }
}

总结

1、环形问题可以用遍历两遍+索引求余的方法处理。
2、用单调栈可以一次遍历就找出左右第一个比当前元素高/矮的值。
3、单调栈相关题目一定要确定,栈口元素和当前遍历的元素三种大小关系(>,<,=)下的处理方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/601590.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

听说今年 “金9银10” 变成 金七银八 了...

眼下虽然才6月份&#xff0c;但真正的金9银10已经悄然开始。从认识的HR那得知&#xff0c;有些公司甚至在6月就开始布局了。。而年前偃旗息鼓的&#xff0c;年后也势必加速进入这波抢人大战&#xff01; 因此&#xff0c;真的要等到9、10月份再做准备的话&#xff0c;就晚了。…

6-TET, SE,6-TET, SE 6-(4,6-二氯三嗪基)氨基荧光素,一种流行的氨基反应荧光探针

文章关键词&#xff1a;荧光反应探针 中文名称&#xff1a;6-TET, SE 6-(4,6-二氯三嗪基)氨基荧光素 英文名称&#xff1a;6-TET, SE 规格标准&#xff1a;10mg&#xff0c;25mg&#xff0c;50mg CAS&#xff1a;N/A 分子式&#xff1a;C25H11Cl4NO9 分子量&#xff1a;611.17 …

win命令窗口的常用命令

文章目录 一、端口号1、查看所有端口netstat -ano2、查看指定端口情况3、终止改端口4、 二、硬盘操作2.0、进入磁盘管理2.1、 查看磁盘2.2、 选择磁盘2.3、 查看分区2.4、 选择分区2.5、 进入分区删除分区 参考文章 一、端口号 1、查看所有端口netstat -ano netstat -ano 2、查…

【ZLM】ZLM源码阅读一

目录 初始化 RTP RTSP RTMP TCPServer的初始化 参考文档 初始化 RTP RTSP RTMP TCPServer的初始化 参考文档 本文参考&#xff1a; (17条消息) 《ZLToolKit源码学习笔记》&#xff08;20&#xff09;网络模块之TcpServer_秦时小的博客-CSDN博客 RTP https://blog.csdn.…

在嵌入式linux板子上搭建NFS服务器

使用portmapnfs-utils的工具在hi3536的linux系统上搭建nfs服务器&#xff0c;使用VM虚拟机中的ubuntu作为客户端挂载&#xff0c;进行文件的读写。 编译能够支持nfs server的内核 1.首先对linux内核进行修改&#xff0c;让linux内核支持nfs服务器的功能&#xff0c;修改方式是…

通过yum:mysql5.6-msyql5.7-mysql8.0升级之路

一 前言 mysql的yum源 https://dev.mysql.com/downloads/repo/yum/ https://dev.mysql.com/get/mysq57-community-release-el7-7.noarch.rpm服务器信息 2c2g40GB [rootlocalhost ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) [rootlocalhost ~]# una…

如何进行测试优先级划分

一般测试的优先级是从这三种情况进行划分&#xff1a;新模块测试、回归测试和特殊功能测试。 1、新单元模块的测试优先级 新模块单元&#xff0c;内部业务逻辑测试&#xff0c;优先级第一。新模块单元与其他模块的集成测试优先级第二。 对于新模块的测试&#xff0c;应以完成单…

消息队列的使用

消息队列 概念&#xff1a; 消息队列是System V IPC对象的一种 消息队列的使用&#xff1a; 发送端&#xff1a; 1 申请Key 2打开/创建消息队列 msgget 3向消息队列发送消息 msgsnd 接收端&#xff1a; 1打开/创建消息队列 msgget 2从消息队列接收消息 msgrcv …

一个29岁软件测试工程师的7年,太真实了...

当前就业环境&#xff0c;裁员、失业消息满天飞&#xff0c;好像有一份工作就不错了&#xff0c;更别说高薪了。其实这只是一方面&#xff0c;而另一方面&#xff0c;各大企业依然求贤若渴&#xff0c;高技术人才依然紧缺&#xff0c;只要你技术过硬&#xff0c;拿个年包50w不是…

Jetpack Compose 的最佳处理运行时权限的方法

Jetpack Compose 的最佳处理运行时权限的方法 如果您的应用安装在运行Android 6.0&#xff08;API级别23&#xff09;或更高版本的设备上&#xff0c;则必须按照本指南中的步骤为用户请求运行时权限。 在Jetpack Compose中获取运行时权限有两种方法。 使用Activity Result使用…

算法与数据结构-复杂度分析

文章目录 什么是大 O 复杂度表示法为什么要用大 O 复杂度表示法如何分析一段代码的时间复杂度1、只关注循环执行次数最多的一段代码2、加法法则&#xff1a;总复杂度等于量级最大的那段代码的复杂度3、乘法法则&#xff1a;嵌套代码的复杂度等于嵌套内外代码复杂度的乘积 几种常…

计算机网络常见面试题

参考:小林coding 1.TCP/IP模型 2.说一下TCP的三次握手? 第一次握手:客户端向服务端发起建立连接请求,客户端会随机生成一个起始序列号x,客户端向服务端发送的字段中包含标志位SYN=1,序列号seq=x。第一次握手前客户端的状态为CLOSE,第一次握手后客户端的状态为SYN-SENT。…

海外网红合作攻略:如何在转化率战场上脱颖而出

在当今社交媒体时代&#xff0c;与海外网红合作已成为企业推广产品与服务的重要途径之一。与海外网红合作不仅可以扩大品牌知名度&#xff0c;还能够吸引更多目标受众。然而&#xff0c;仅仅与网红合作并不能保证高转化率。本文Nox聚星将详细介绍几种有效的方法&#xff0c;帮助…

DDR跑不到速率,调整下PCB叠层就搞掂了?

高速先生成员--姜杰 关于DDR的案例&#xff0c;高速先生已经分享过很多期的文章了&#xff0c;有通过修改主控芯片的驱动解决问题的&#xff0c;有通过修改PCB走线的拓扑来解决问题的&#xff0c;也有通过调节端接电阻来解决问题的&#xff0c;相对于下面即将登场的解决方法而…

【Java|golang】2559. 统计范围内的元音字符串数

给你一个下标从 0 开始的字符串数组 words 以及一个二维整数数组 queries 。 每个查询 queries[i] [li, ri] 会要求我们统计在 words 中下标在 li 到 ri 范围内&#xff08;包含 这两个值&#xff09;并且以元音开头和结尾的字符串的数目。 返回一个整数数组&#xff0c;其中…

Flutter学习一:安装配置

目录 1 官方文档 2 安装配置 2.1 第一步&#xff1a;下载配置Flutter 2.2 第二步&#xff1a;下载配置Android Studio 2.3 第三步&#xff1a;下载配置VScode 1 官方文档 在 Windows 操作系统上安装和配置 Flutter 开发环境 - Flutter 中文文档 - Flutter 中文开发者网站…

从一个励志故事,读懂网络工程师的职业规划

这个励志故事主人公的起点&#xff0c;是在伟创力的工厂打螺丝。 改变 他很早不上学了&#xff0c;出社会的时候学历和技能什么也没有&#xff0c;就只能去工厂打螺丝。他在伟创力的工厂打螺丝打了好多年&#xff0c;在接近30岁的时候&#xff0c;他哥跟他说&#xff1a;你不能…

黑客零基础从入门到精通学习成长路线(超多图、非常详细),看完这一篇就够了

前言 近几年&#xff0c;随着移动互联网、大数据、云计算、人工智能等新一代信息技术的快速发展&#xff0c;围绕网络和数据的服务与应用呈现爆发式增长&#xff0c;丰富的应用场景下暴露出越来越多的网络安全风险和问题。 但是&#xff0c;我国网络安全整体投入不高。网络安…

基于YOLOv7开发构建红外高空小目标检测识别分析系统

基于yolo系列的模型开发构建红外场景下的目标检测系统&#xff0c;在我之前的文章中已经有好几次实践了&#xff0c;感兴趣的话可以自行移步阅读&#xff1a; 《红外海洋目标检测实践&#xff0c;基于目标检测模型识别红外海洋目标》 《基于YOLO开发构建红外场景下无人机航拍…

【Java基础】简单参数和springboot方式形参传递法

一、知识点整理 1、Postman 2、在原始的web程序中获取请求参数需通过HttpServletRequest对象手动获取 二、操作步骤 1、参考链接1下载postman&#xff0c;并创建工作空间。 2、打开idea&#xff0c;新建项目&#xff0c;选择Spring Initializar&#xff0c;依赖库勾选Web下…