Day59【单调栈】503.下一个更大元素II、42.接雨水

news2024/11/24 4:18:37

503.下一个更大元素II

力扣题目链接/文章讲解

视频讲解

本题和739.每日温度很相似,只不过是循环数组

一种处理循环的方式是,直接把两个数组拼接在一起,然后使用单调栈求下一个最大值

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        // 拼接一个新的nums
        vector<int> nums1(nums.begin(), nums.end());
        nums.insert(nums.end(), nums1.begin(), nums1.end());
        // 用新的nums大小来初始化result
        vector<int> result(nums.size(), -1);
        if (nums.size() == 0) return result;

        // 开始单调栈
        stack<int> st;
        st.push(0);
        for (int i = 1; i < nums.size(); i++) { 
            if (nums[i] < nums[st.top()]) st.push(i); 
            else if (nums[i] == nums[st.top()]) st.push(i);
            else { 
                while (!st.empty() && nums[i] > nums[st.top()]) {    // 千万别忘了判断st非空
                    result[st.top()] = nums[i];
                    st.pop();
                }    // 弹出所有比入栈元素小的栈顶元素
                st.push(i);    // 然后再入栈,这样能保持栈顶到栈底元素单调递增
            }
        }
        // 最后再把结果集即result数组resize到原数组大小
        result.resize(nums.size() / 2);
        return result;
    }
};

另一种处理这种循环的方式是,利用取余 % 模拟循环 

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        vector<int> ans(nums.size(), -1);
        stack<int> st;
        st.push(0);
        for (int i = 1; i < 2 * nums.size() - 1; ++i) {    // 2*nums.size()-1就相当于遍历数组两次
            int index = i % nums.size();
            if (nums[index] <= nums[st.top()])
                st.push(index);
            else
            {
                while (!st.empty() && nums[index] > nums[st.top()]) {    // 注意判非空
                    ans[st.top()] = nums[index];    // 出栈时记录结果在下标位置
                    st.pop();
                }
                st.push(index);    // 这个时候再入栈不会破坏单调性
            }
        }
        return ans;
    }
};

注意,我们单调栈中存的是下标,单调性看的是下标所对应的值 

为什么不直接存值?因为如果存值,出栈的时候需要记录,此时没办法通过这个值确定应该记录在哪个下标位置;而如果存下标,出栈的时候需要记录,可直接通过下标确定应该记录在哪个位置,也能通过下标获取值

42.接雨水 

力扣题目链接/文章讲解 

视频讲解 

本题怎么求能接的雨水?可以看出每一列雨水的高度,取决于,该列左侧最高的柱子和右侧最高的柱子中最矮的那个柱子的高度 

大致过程如下 

  • 找到每一列右侧最高的柱子
  • 找到每一列左侧最高的柱子
  • 遍历每一列,用每一列两侧最高柱子的最小值减去该列高度,就是该列能接的雨水 

这样一列一列算的代码逻辑如下 

class Solution {
public:
    int trap(vector<int>& height) {

        if (height.size() <= 2) return 0;

        vector<int> maxLeft(height.size());
        vector<int> maxRight(height.size());

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

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

        // 求和
        int sum = 0;
        for (int i = 1; i < height.size() - 1; i++) {   // 首尾列不接雨水
            int count = min(maxLeft[i], maxRight[i]) - height[i];
            if (count > 0) sum += count;
        }
        
        return sum;
    }
};

本题也可以用单调栈解法!单调栈是寻找任一个元素的右边或者左边第一个比自己大或者小的元素的位置 

放在本题中,通过单调栈能够一行一行算所接的雨水量 

从图中可以看出,一行一行计算,需要知道这一行雨水的高度和宽度

雨水高度是 min(凹槽左边高度, 凹槽右边高度) - 凹槽底部高度 

雨水的宽度是 凹槽右边的下标 - 凹槽左边的下标 - 1(因为只求中间宽度) 

单调栈处理逻辑和之前的题目差不多,只不过入栈时涉及到出栈的时候记录操作稍微难了点

我们需要关注 

  • 凹槽底部高度就是栈顶元素
  • 凹槽右边的高度就是待入栈元素
  • 凹槽左边的高度就是栈顶的下一个元素 

代码如下

class Solution {
public:
    int trap(vector<int>& height) {
        if (height.size() <= 2) return 0; // 可以不加
        stack<int> st; // 存着下标,计算的时候用下标对应的柱子高度
        st.push(0);
        int sum = 0;
        for (int i = 1; i < height.size(); i++) {
            if (height[i] <= height[st.top()]) {
                st.push(i);
            } else {
                while (!st.empty() && height[i] > height[st.top()]) { // 注意这里是while
                    int mid = st.top(); // 凹槽底部高度
                    st.pop();
                    if (!st.empty()) {
                        int h = min(height[st.top()]/*凹槽左边高度*/, height[i]/*凹槽右边高度*/) - height[mid]; 
                        int w = i - st.top() - 1; // 注意减一,只求中间宽度
                        sum += h * w;
                    }
                }
                st.push(i);
            }
        }
        return sum;
    }
};

本题也多看视频模拟过程 


回顾总结 

背住单调栈的框架

接雨水那道题重点掌握按列计算的方法,更易于理解 

 

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

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

相关文章

【JUC基础】13. 线程池(二)

目录 1、前言 2、Java实现线程池 2.1、Executors框架 2.2、newFixedThreadPool 2.3、newCachedThreadPool 2.4、newSingleThreadExecutor 2.5、newScheduledThreadPool 2.5.1、scheduleAtFixedRate 2.5.2、scheduleWithFixedDelay 2.5.3、异常中断 3、execute()和sub…

大数据挖掘企业服务平台(TipDM大数据挖掘建模平台)-快速构建数据挖掘工程

“TipDM大数据挖掘建模平台”&#xff08;以下简称平台&#xff09;是由广东泰迪智能科技股份有限公司自主研发&#xff0c;基于Python引擎的数据挖掘建模平台。使用平台配置的开箱即用的算法组件&#xff0c;用户可在没有编程基础的情况下&#xff0c;通过拖拽的方式进行操作&…

蓝牙规范系列--经典蓝牙概述(第一篇)

一、目的 从本篇开始介绍经典蓝牙的基础知识&#xff0c;内容较多故会分成多篇进行介绍。 经典蓝牙&#xff08;BR/EBR&#xff09;射频&#xff08;物理层PHY&#xff09;工作在免授权的2.4G ISM频段&#xff08;2400 - 2483.5 MHz&#xff09;&#xff0c;使用跳频技术来对抗…

基于java的班级管理系统的设计与实现

一:需求分析 1.功能需求 1).能够实现对班级学生基本资料的录入,包括学生的学号,姓名,性别,所学专业,家庭住址以及出生年月等。 2).能够实现对学生基本资料的修改。 3).根据学号对学生资料进行查询。 4).能够删除某些学生的资料。 二:总体设计 本班级管理系统共有6…

静态Web服务器搭建

文章目录 一&#xff0c;安装Apache软件&#xff08;一&#xff09;Apache软件安装&#xff08;二&#xff09;Apache软件管理&#xff08;三&#xff09;Apache软件基本设置&#xff08;四&#xff09;测试Apache服务器 二&#xff0c;Apache服务器的配置文件&#xff08;一&a…

【C++】结构体 - 定义和使用,结构体数组,结构体指针,结构体嵌套结构体,结构体做函数参数,结构体 const

文章目录 1. 定义和使用2. 结构体数组3. 结构体指针4. 结构体嵌套结构体5. 结构体做函数参数6. 结构体 const 1. 定义和使用 结构体属于用户自定义的数据类型&#xff0c;允许用户存储不同的数据类型。 struct 结构体 {结构体成员列表}; 通过结构体创建变量的方法有三种&…

2023,智能硬件的AIGC“又一春”

​ 文|智能相对论 作者|佘凯文 消费电子产品风光不再&#xff0c;特别是自去年以来&#xff0c;电子消费市场经历了一整年的寒潮袭击&#xff0c;智能手机等产品达到10年消费谷底&#xff0c;PC出货量整体下降16%&#xff0c;不仅如此&#xff0c;包括平板、可穿戴设备也一改…

URP Shader FrameBuffer Fetch Mali Crash

1&#xff09;URP Shader FrameBuffer Fetch Mali Crash ​2&#xff09;Unity模型Lightmap UV相关的疑问 3&#xff09;动画上下半身融合问题 4&#xff09;AnimatorControllerPlayable.PrepareFrame函数在什么情况下调用 这是第338篇UWA技术知识分享的推送&#xff0c;精选了…

如何将 HTML 字符串转换成 DOM 对象:用 DOMParser

如何将 HTML 字符串转换成 DOM 对象&#xff1a;用 DOMParser 一、问题描述 有的时候我们需要处理一些 HTML 字符串&#xff0c;比如我需要从下方 HTML 字符串中提取每个 <a> 标签的内容和属性。 <pre><a href"cc1245.jpg">cc1245.jpg</a>…

将ipa文件上架苹果应用商店详细教程

使用windows电脑打包好uniapp的ios应用之后&#xff0c;还有一个麻烦事&#xff0c;就是需要将这个打包好的ipa格式的文件&#xff0c;上架到苹果的应用商店。用户才能安装。 而苹果提供的上传工具&#xff0c;比如xcode或transports&#xff0c;只能安装在mac电脑&#xff0c…

国产AIGC大模型汇总

“ 随着ChatGPT和GPT-4的出现&#xff0c;直接引爆了全球的AIGC大模型市场&#xff01;为了赶上这一波热潮&#xff0c;国内的大厂和创业公司也纷纷内卷起来&#xff0c;相继发布了自己的大模型。但是到目前为止&#xff0c;没有一个大模型能与ChatGPT相提并论&#xff0c;更比…

【算法系列之二叉树III】leetcode236. 二叉树的最近公共祖先

617.合并二叉树 力扣题目链接 给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&#xff0c;两棵树上的一些节点将会重叠&#xff08;而另一些不会&#xff09;。你需要将这两棵树合并成一棵新二叉树。合并的规则是&…

MySQL 三万字精华总结 + 面试100 问,和面试官扯皮绰绰有余

MySQL 三万字精华总结 面试100 问&#xff0c;和面试官扯皮绰绰有余 写在之前&#xff1a;不建议那种上来就是各种面试题罗列&#xff0c;然后背书式的去记忆&#xff0c;对技术的提升帮助很小&#xff0c;对正经面试也没什么帮助&#xff0c;有点东西的面试官深挖下就懵逼了。…

linuxOPS基础_linux文本文件查看

vi/vim vim文档编辑操作太多了,可以看这篇单独介绍vim的文章>https://blog.csdn.net/weixin_44368963/article/details/130963920 cat查看文件 命令&#xff1a;cat 作用&#xff1a;查看文件内容 语法&#xff1a;#cat 文件名称 ​ #cat 文件1 文件2 > 文件3 **特别注…

如何利用CiteSpace快速锁定领域内最新研究热点并制作精美的可视化专题图?

【基于Citespace和vosviewer文献计量学相关论文 】 ​ 01 文献计量学方法与应用 1. 文献计量学方法基本介绍 2. 与其他综述方法区别联系 3. 各学科领域应用趋势近况 4. 主流分析软件优缺点对比 5. 经典高分10SCI思路复盘 6. 软件安装与Java环境配置 02 主题确定、数据检…

Vue+springboot校园跳蚤二手市场管理系统

摘 要 本毕业设计的内容是设计并且实现一个基于Springboot框架的校园跳蚤市场管理系统。它是在Windows下&#xff0c;以MYSQL为数据库开发平台&#xff0c;Tomcat网络信息服务作为应用服务器。校园跳蚤市场管理系统的功能已基本实现&#xff0c;主要包括用户、卖家、商品分类…

中国存储竞争新格局:曙光掌舵分布式存储市场

近日&#xff0c;赛迪顾问发布了《中国分布式存储市场研究报告&#xff08;2023&#xff09;》。 作为数字经济的底座&#xff0c;数据存储的重要性日益凸显。 近年来&#xff0c;凭借高性能、高可靠性、高可扩展性等优势&#xff0c;基于分布式架构的分布式存储迎来了蓬勃发…

基于SpringBoot+vue的火车订票管理系统设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…

动静态库的区别

(5条消息) linux-动态库制作与使用_云的小站的博客-CSDN博客 (5条消息) linux-静态库制作与使用_云的小站的博客-CSDN博客 目录 编译区别 使用不同编译的可执行程序。 推荐使用动态链接 动态链接具有以下优缺点 编译区别 动态库&#xff1a;代码不加载到可执行程序中&am…

Java:Mybatis-Plus自动填充功能配置和使用

Mybatis-Plus可以实现字段自动填充功能 文档 https://baomidou.com/pages/4c6bcf/ 目录 需求数据库设置默认值通过代码的方式进行自动填充配置自动填充设置方式一设置方式二 测试依赖pom.xml 需求 我们需要自动填充的字段&#xff1a; 插入数据时自动填充&#xff1a;creat…