代码随想录算法训练营第六十二天 |503.下一个更大元素II、42. 接雨水

news2024/12/23 7:24:44

一、503.下一个更大元素II 

题目链接/文章讲解:代码随想录

思考:关于单调栈的处理在题解739. 每日温度中已经出现过了,剩下的是如何处理循环数组

比较直白的方法是

将两个nums数组拼接在一起,使用单调栈计算出每一个元素的下一个最大值,最后再把结果集即result数组resize到原数组大小就可以了。

这个思路确实比较直观,但做了很多无用操作,例如修改了nums数组,而且最后还要把result数组resize回去。resize是O(1)的操作,但扩充nums数组相当于多了一个O(n)的操作。

其实也可以不扩充nums,而是在遍历的过程中模拟走了两边nums。

代码实现: 

// 版本一
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()]) {
                    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> result(nums.size(), -1);
        if (nums.size() == 0) return result;
        stack<int> st;
        st.push(0);
        for (int i = 1; i < nums.size() * 2; i++) { 
            // 模拟遍历两边nums,注意一下都是用i % nums.size()来操作
            if (nums[i % nums.size()] < nums[st.top()]) st.push(i % nums.size());
            else if (nums[i % nums.size()] == nums[st.top()]) st.push(i % nums.size()); 
            else {
                while (!st.empty() && nums[i % nums.size()] > nums[st.top()]) {
                    result[st.top()] = nums[i % nums.size()];
                    st.pop();
                }
                st.push(i % nums.size());
            }
        }
        return result;
    }
};

版本二精简版:

// 版本二
class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        vector<int> result(nums.size(), -1);
        if (nums.size() == 0) return result;
        stack<int> st;
        for (int i = 0; i < nums.size() * 2; i++) {
            // 模拟遍历两边nums,注意一下都是用i % nums.size()来操作
            while (!st.empty() && nums[i % nums.size()] > nums[st.top()]) {
                result[st.top()] = nums[i % nums.size()];
                st.pop();
            }
            st.push(i % nums.size());
        }
        return result;
    }
};

二、42. 接雨水

题目链接/文章讲解:代码随想录

思考:

接雨水这道题目,我们正需要寻找一个元素,右边最大元素以及左边最大元素,来计算雨水面积,因此使用单调栈。

1.首先单调栈是按照行方向来计算雨水

2.使用单调栈内元素的顺序

从小到大

3.遇到相同高度的柱子怎么办

遇到相同的元素,更新栈内下标,就是将栈里元素(旧下标)弹出,将新元素(新下标)加入栈中。

4.栈里要保存什么数值

栈里就存放下标就行,想要知道对应的高度,通过height[stack.top()] 就知道弹出的下标对应的高度。

单调栈处理逻辑

主要就是三种情况

  • 情况一:当前遍历的元素(柱子)高度小于栈顶元素的高度 height[i] < height[st.top()]
  • 情况二:当前遍历的元素(柱子)高度等于栈顶元素的高度 height[i] == height[st.top()]
  • 情况三:当前遍历的元素(柱子)高度大于栈顶元素的高度 height[i] > height[st.top()]

如果当前遍历的元素(柱子)高度大于栈顶元素的高度,此时就出现凹槽了

处理方式就是栈顶和栈顶的下一个元素以及要入栈的元素,三个元素来接水!

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

雨水的宽度是 凹槽右边的下标 - 凹槽左边的下标 - 1

当前凹槽雨水的体积就是:h*w

int h = min(height[st.top()], height[i]) - height[mid];
        int w = i - st.top() - 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);
            } if (height[i] == height[st.top()]) {  // 情况二
                st.pop(); // 其实这一句可以不加,效果是一样的,但处理相同的情况的思路却变了。
                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;
    }
};

精简版:

class Solution {
public:
    int trap(vector<int>& height) {
        stack<int> st;
        st.push(0);
        int sum = 0;
        for (int i = 1; i < height.size(); i++) {
            while (!st.empty() && height[i] > height[st.top()]) {
                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/1084742.html

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

相关文章

K8S:Rancher管理 Kubernetes 集群

文章目录 一.Rancher 简介1.Rancher概念2.Rancher 和 k8s 的区别 二.Rancher 安装及配置1.安装 rancher2.登录 Rancher 平台3.Rancher 管理已存在的 k8s 集群4.Rancher 部署监控系统5.使用 Rancher 仪表盘管理 k8s 集群 三.拓展1.Rancher和kubesphere相比较2.K3S和K8S相比较 一…

高德地图获取行政区域并且获取经纬度

我们的需求是获取行政图的切片图&#xff0c;需要四个角的经纬度代码如下 <!doctype html> <html><head><meta charset"utf-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport…

Acer宏碁掠夺者战斧700笔记本PH717-71原装出厂Win10系统1903工厂模式镜像

宏基原厂系统自带所有驱动、PREORTOR风扇键盘控制中心、Office办公软件、出厂主题壁纸、系统属性Acer宏基专属的LOGO标志、 Acer Care Center、Quick Access等预装程序 下载链接&#xff1a;https://pan.baidu.com/s/1s-I5vLihXBqdEmtd9MOZxQ?pwdnfku 所需要工具&#xff1a…

TSINGSEE青犀视频AI分析/边缘计算/AI算法·厨师帽检测功能——多场景高效运用

在餐饮厂房等场景中&#xff0c;为保障食品安全与卫生&#xff0c;后厨操作人员规范着装要求是必不可少的。由于后厨温度较高&#xff0c;环境较为恶劣&#xff0c;很多后厨人员为自身方便不按照规定佩戴厨师帽和着厨师服&#xff0c;为切实解决此问题&#xff0c;TSINGSEE青犀…

迅镭激光GI系列高功率激光切割机成功中标覆铜板龙头企业HZ公司

新材料被称为“发明之母”和“产业粮食”&#xff0c;是现代科技发展的基础&#xff0c;和信息技术、生物技术一起并称为最重要和最具发展潜力的三大领域&#xff0c;它是我国先进制造业发展的支撑和保障&#xff0c;对推动技术创新、促进制造业优化升级、保障国家安全等具有重…

选C4D还是Blender?新手设计师不容错过的全面比较

&#xfeff;近年来&#xff0c;随着3D设计行业的不断发展&#xff0c;可供设计师使用的软件也越来越多。设计师们在选择合适的3D软件时感到难以抉择。在3D建模和动画制作领域&#xff0c;Blender和Cinema 4D (简称C4D)都是备受赞誉的软件。那么&#xff0c;到底哪个软件更适合…

亚马逊美国站加拿大站儿童自行车合规标准是什么?如何办理?需要那些信息?

亚马逊美国站儿童自行车 儿童自行车是一种后轮完全由人力驱动&#xff0c;同时座椅高度不超过 25 英寸的两轮车&#xff0c;也可以是专为 12 岁或以下儿童设计或供其使用的自行车。 此政策不适用于仅根据个人订单要求制造&#xff0c;而未经过库存零件或生产零件装配流程的自…

接口性能测试方案

01 性能测试术语解释 1. 响应时间 响应时间即从应用系统发出请求开始&#xff0c;到客户端接收到最后一个字节数据为止所消耗的时间。响应时间按软件的特点再可以细分&#xff0c;如对于一个 C/S 软件的响应时间可以细分为网络传输时间、应用服务器处理时间、数据库服务器处理时…

【算法笔记】LCR 086. 分割回文串

基本思想是使用回溯法&#xff0c;回溯法都可以将问题划分为一个解空间树&#xff1a;假设字符串s为"aab"&#xff0c;那么我们可以使用深度优先搜索去构建解空间树&#xff1a; dfs遍历出来的第一个序列是[a, a, b]&#xff0c;显然该序列都是回文子串&#xff0c;…

程序员的注释之争:缘起与解决

程序员的注释之争&#xff1a;缘起与解决 前言一、为什么有人写代码不写注释&#xff1f;1.1 注释的理念1.2 时间压力1.3 缺乏标准 二、为什么有人坚持写注释&#xff1f;2.1 可维护性2.2 团队合作2.3 知识传承 三、解决争议&#xff1a;如何正确使用注释3.1 注释的角色3.2 注释…

香港服务器租用流程步骤有哪些?

​  香港服务器的租用相对来说较为简单&#xff0c;无需ICP备案认证&#xff0c;而且中国香港作为全球性的网络枢纽地&#xff0c;不管是境外跟境内都具备比较好的访问效果&#xff0c;由此也有大量中小型企业陆续选择到香港服务器。但&#xff0c;由于租用香港服务器时&…

python:使用随机森林回归模型进行数据预测

作者:CSDN @ _养乐多_ 在本篇博客中,我们将介绍如何使用Python编程语言和一些主要的数据科学工具(pandas、numpy、sklearn等)来进行数据预测。我们将使用随机森林回归模型,该模型是一种强大的机器学习算法,适用于回归问题,例如预测连续性变量的值。我们将演示如何准备数…

四川竹哲电子商务有限公司培训服务引领你走向成功

在这个数字时代&#xff0c;抖音不仅成为了一个全球热门的社交平台&#xff0c;更是一个充满商机的创业舞台。四川竹哲电子商务有限公司&#xff0c;作为一家专注于抖音培训服务的领先机构&#xff0c;将帮助你在这片蓝海中独领风骚&#xff0c;实现创业梦想&#xff01; 一、强…

DataPath实现渐变效果

Android的vector矢量图很好用&#xff0c;可以画出保证清晰度的任意图形。但是Android Nougat之前的VectorDrawable不支持渐变色&#xff0c;如果要使用渐变色就要使用png图片或者自定义GradientDrawable。这么明显的不足&#xff0c;肯定是要修补上呀&#xff0c;API 24中的Ve…

Zabbix安装出现必要条件检查失败

问题描述 今天在某朋友部署新环境的Zabbix时&#xff0c;系统出现如下的检查失败情况。此环境的基础部分不是我负责&#xff0c;而是其它项目共存的PHP环境&#xff0c;也是挺奇怪的。一般来说&#xff0c;不应该将zabbix与其它系统部署在一起&#xff0c;没有条件哪怕时Docke…

Pyside6 QtabWidget

Pyside6 QtabWidget QtabWidget使用QtabWidget常用方法设置标签页的标题程序设置界面设置 设置当前显示的标签页程序设置界面设置 删除标签页程序设置界面设置 添加标签页程序设置界面设置 例程界面程序主程序 QtabWidget是Pyside6中的一个标签页控件&#xff0c;其作用可以是让…

MyBatis底层源码分析

&#x1f384;欢迎来到边境矢梦的csdn博文&#x1f384; &#x1f384;本文主要梳理MyBatis底层源码分析 &#x1f384; &#x1f308;我是边境矢梦&#xff0c;一个正在为秋招和算法竞赛做准备的学生&#x1f308; &#x1f386;喜欢的朋友可以关注一下&#x1faf0;&#x1f…

WebDAV之π-Disk派盘 + 元思笔记

元思笔记是一款面向大众的卡片笔记软件,解决了笔记类软件的一个痛点:绝大多数人都很难坚持每天记一点东西。任何笔记工具,不论是纸笔还是电子,能够让人坚持记录就是好工具。 元思笔记是一款基于卢曼卡片盒的移动端卡片笔记软件;隐私优先,本地存储数据且支持云备份;丰富的…

AnyTransition/过渡动画, MatchedGeometryEffect/匹配几何动画效果 的使用

1. AnyTransition 过渡动画效果 1.1 创建过度动画案例 AnyTransitionBootcamp.swift import SwiftUI/// 旋转修饰 View struct RotateViewModifier :ViewModifier{let rotation: Doublefunc body(content: Content) -> some View {content.rotationEffect(Angle(degrees: r…

多目标追踪数据集分享

SportsMOT: A Large Multi-Object Tracking Dataset in Multiple Sports Scenes SportsMOT是一个新的大规模多目标追踪数据集&#xff0c;专注于多样化的体育场景&#xff0c;其中需要跟踪场上的所有运动员。该数据集包括来自篮球、排球和足球等三类体育项目的240个视频序列&am…