算法学习day59

news2024/11/24 19:58:51

算法学习day59

  • 1.力扣503.下一个更大元素II
    • 1.1 题目描述
    • 1.2 分析
    • 1.3代码
  • 2.力扣42. 接雨水
    • 2.1 题目描述
    • 2.2 分析
    • 2.3 代码
  • 3.参考资料

1.力扣503.下一个更大元素II

1.1 题目描述

题目描述:

给定一个循环数组(最后一个元素的下一个元素是数组的第一个元素),输出每个元素的下一个更大元素。数字x的下一个更大元素是按数组遍历顺序,这个数字之后的第一个比它更大的数,循环搜索它的下一个更大的数。如果不存在,输出-1。

例1:

输入:[1, 2, 1]

输出:[2, -1 , 2]

解释:第一个1的下一个更大的数是2;数字2找不到下一个更大的数输出-1;第二个1的下一个最大的数需要循环搜索,结果也是2.

1.2 分析

当我们需要在一个循环数组中找到每个元素的下一个更大元素时,可以使用单调栈的思想来解决这个问题。

假设我们有一个循环数组 nums,为了方便处理,我们可以将它复制一份拼接到原数组的末尾,从而得到一个长度为原数组两倍的新数组 nums。这样处理后,我们就可以把循环数组 nums 看成一个普通的数组,从而用单调栈来解决。

接下来就是单调栈的操作:

我们用一个栈来存储数组元素的下标。首先,我们将数组的第一个元素的下标 push 进栈中,即 st.push(0)。

然后,从数组的第二个元素开始遍历数组,对于数组的每个元素 nums[i],如果它小于或等于栈顶元素所对应的元素 nums[st.top()],则将它的下标 i push 进栈中,表示它的下一个更大元素还没有找到

如果 nums[i] 大于栈顶元素所对应的元素 nums[st.top()],则说明栈顶元素的下一个更大元素就是 nums[i],我们可以将栈顶元素所对应的结果 result[st.top()] 赋值为 nums[i],表示它的下一个更大元素是 nums[i],然后将栈顶元素 pop 出栈,继续判断新的栈顶元素和当前元素的大小关系

重复执行上述操作,直到遍历完整个数组。最后,我们得到的结果数组 result 中存储的就是每个元素的下一个更大元素了。由于我们把原数组复制拼接到末尾,所以最后需要将结果数组 result 调整为原数组的大小,即执行 result.resize(nums.size() / 2)。

时间复杂度为 O(n),因为每个元素只会入栈出栈一次。

1.3代码

class Solution {
public:
    vector<int> nextGreaterElements(vector<int>& nums) {
        // 拼接一个新的nums,使其成为长度为原数组两倍的数组
        vector<int> nums1(nums.begin(), nums.end());
        // 将nums1中的所有元素插入到nums的末尾,从而得到一个新的nums
        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 {
                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;
    }
};

2.力扣42. 接雨水

2.1 题目描述

题目描述:

给定n个非负整数表示每个宽度为1的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

在这里插入图片描述
输入:height=[0,1,0,2,1,0,1,3,2,1,2,1]

输出:6

解释:上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] 表示的高度图,在这种情况下,可以接 6 个单位的雨水(蓝色部分表示雨水)。

2.2 分析

双指针法:

按照列来计算,宽度为1.将每一列的雨水高度求出来即可。

计算该列取决于左侧最高柱子和右侧最高柱子中最矮小的减去自身。转换为公式如下:

计算公式:min(左侧最高,右侧最高)- 本身高度。

结合下图更好理解:
在这里插入图片描述
列4 左侧最高的柱子是列3,高度为2(以下用lHeight表示)。

列4 右侧最高的柱子是列7,高度为3(以下用rHeight表示)。

列4 柱子的高度为1(以下用height表示)

那么列4的雨水高度为 列3和列7的高度最小值减列4高度,即: min(lHeight, rHeight) - height。

列4的雨水高度求出来了,宽度为1,相乘就是列4的雨水体积了。
同样的操作,从头遍历一遍所有的列,然后求出每一列雨水的体积。相加就是总雨水的体积了。注:第一个柱子和最后一个柱子不接雨水

代码如下:

for(int i = 0 ; i < height.size() ; i++){
    // 第一个柱子和最后一个柱子不接雨水、
    if(i == 0 || i == height.size() - 1) continue;
}

在for循环中求左右两边最高柱子,代码如下:

int rHeight = height[i]; // 记录右边柱子的最高高度
int lHeight = height[i]; // 记录左边柱子的最高高度
for(int r = i+1 ; i height.size(); r++){
    if(height[r] > rHeight) rHeight = height[r];
}
for(int l = i -1 ; l>= 0; l--){
    if(height[l] > lHeight) lHeight = height[l];
}

最后计算该列的雨水高度:

int h = min(lHeight,rHeight) -height[i];
if(h>0) sum += h;// 注意只有h大于零的时候,才统计到总和之中。

优化:

之前为了得到两边的最高高度,使用双指针来遍历,每到一个柱子都行两边遍历一遍。考虑把每一个位置的左边最高高度记录在一个数组上(maxLeft),右边最高高度记录在一个数组上(maxRight),即可避免重复。

当前位置,左边的最高高度是前一个位置的左边最高高度和本高度的最大值

从左向右遍历:maxLeft[i] = max(height[i],maxLeft[i-1])

从右向左遍历:maxRight[i] = max(height[i], maxRight[i+1])

2.3 代码

class Solution {
public:
    int trap(vector<int>& height) {
        // 如果height的长度小于等于2,那么无法形成水坑,直接返回0
        if (height.size() <= 2) return 0;
        // 初始化一个数组,用来记录每个柱子左边柱子最大高度
        vector<int> maxLeft(height.size(), 0);
        // 初始化一个数组,用来记录每个柱子右边柱子最大高度
        vector<int> maxRight(height.size(), 0);
        // 获取maxRight数组的大小
        int size = maxRight.size();

        // 计算每个柱子左边柱子的最大高度
        maxLeft[0] = height[0]; // 第一个柱子的最大高度就是它本身
        for (int i = 1; i < size; i++) {
            // 当前柱子的左边柱子最大高度,是当前柱子高度和左边柱子的最大高度中较大的那个
            maxLeft[i] = max(height[i], maxLeft[i - 1]);
        }
        // 计算每个柱子右边柱子的最大高度
        maxRight[size - 1] = height[size - 1]; // 最后一个柱子的最大高度就是它本身
        for (int i = size - 2; i >= 0; i--) {
            // 当前柱子的右边柱子最大高度,是当前柱子高度和右边柱子的最大高度中较大的那个
            maxRight[i] = max(height[i], maxRight[i + 1]);
        }
        // 计算每个柱子能存放的水量,并将结果求和
        int sum = 0;
        for (int i = 0; i < size; i++) {
            // 当前柱子能存放的水量,等于左边柱子最大高度和右边柱子最大高度中较小的那个减去当前柱子的高度
            int count = min(maxLeft[i], maxRight[i]) - height[i];
            if (count > 0) sum += count;
        }
        return sum; // 返回总的水量
    }
};


3.参考资料

[代码随想录]

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

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

相关文章

【大数据Hadoop】HDFS3.3.1-Namenode-租约管理

租约管理前言LeaseManager.LeaseLeaseManager添加租约 - addLease租约检查 - FsNamesystem.checkLease租约更新 - renewLease删除租约 - removeLease租约检查 - Monitor 线程租约恢复 - Monitor 线程发起租约恢复 - 其他方式发起前言 我们知道 HDFS 文件是 write-once-read-man…

CloudCompare插件开发之点云如何创建、保存并显示?

文章目录0.引言1.创建插件工程2.代码编写3.显示点云4.保存点云0.引言 CloudCompaer是一款优秀的开源软件&#xff0c;在点云处理时可以根据实际要求开发合适的插件&#xff0c;在实际使用中&#xff0c;创建点云、保存点云、显示点云的操作较为基础&#xff0c;为了使这些操作得…

施工组织设计合集

34-6 施工组织设计02017-年亲曼旗大镇市政道路及广场公园园林绿化工程(第一.A1-1五中教学楼施工组织设计A2施工组织设计(方案) 报审表hasuploaded-中建施|组织设计 (22P)安徽大包庄125万吨疏铁矿斜坡道施工组织设计 (修改)宝山万科四季花城施T组织设计 (126P)对税信息培训中心装…

软件测试,月薪还没过万的进来看

目录 前言 一、技能提升 二、多语言掌握 三、团队协作 四、持续学习 五、提高测试效率 六、质量保障 七、职业发展 八、总结 前言 在当今IT行业中&#xff0c;软件测试是一个不可或缺的环节。随着互联网和移动应用的发展&#xff0c;对软件质量的要求也越来越高。因此…

前后端分离架构

前后端分离架构介绍 前后端分离已成为互联网项目开发的业界标准使用方式&#xff0c;将前端和后端的开发进行解耦。并且前后端分离会为以后的大型分布式架构、微服务架构、多端化服务&#xff08;各种客户端&#xff0c;比如浏览器、车载终端、安卓、IOS等&#xff09;打下坚实…

[Netty] FastThreadLocal (十四)

文章目录1.FastThreadLocal介绍2.FastThreadLocal分析3.FastThreadLocal结构分析4.FastThreadLocal方法分析4.1 FastThreadLocal.get()4.2 FastThreadLocal.set()1.FastThreadLocal介绍 FastThreadLocal是Netty中常用的一个工具类, FastThreadLocal所使用的InternalThreadLoca…

[架构之路-159]-《软考-系统分析师》-10-系统分析-6-现有业务流程分析, 系统分析最核心的任务

目录 第 10章 现有系统 分 析 1 0 . 6 现有业务流程分析 10.6.1 业务流程分析槪述 1 . 业务流程分析的步骤 2 . 业务流程分析的方法 10.6.2 业务-流程图TFD 1. T F D 的基本符号 2. TFD的绘制 10.6.3 业务 - 活动图 10.6.4 业务流程建模BPM 1. B P M 概述 2 . 标杆…

Pytest自动化测试框架一些常见的插件

Pytest拥有丰富的插件架构&#xff0c;超过800个以上的外部插件和活跃的社区&#xff0c;在PyPI项目中以“ pytest- *”为标识。 本篇将列举github标星超过两百的一些插件进行实战演示。 插件库地址&#xff1a;http://plugincompat.herokuapp.com/ 1、pytest-html&#xff1…

python机器学习决策树和SVM向量机算法实现红酒分类

1、红酒数据介绍 经典的红酒分类数据集是指UCI机器学习库中的Wine数据集。该数据集包含178个样本&#xff0c;每个样本有13个特征&#xff0c;可以用于分类任务。 具体每个字段的含义如下&#xff1a; alcohol&#xff1a;酒精含量百分比 malic_acid&#xff1a;苹果酸含量&a…

中科大ChatGPT学术镜像小白部署教程,全民都可以拥抱AI

docker…不会用…python不会用…服务器默认python版本3.6不会升级…代理也不会配置…各种命令不会用… 那么下面就是最简单办法&#xff0c;点点点即可【希望有帮助&#xff1f;】 文章目录一、体验镜像地址二、 基本配置2.1 config.py文件2.2 main.py文件三、下载项目四、项目…

FRP内网穿透配置

FRP内网穿透&#xff08;WIN&#xff09; 官方文档&#xff1a;点击进入 1.下载地址&#xff1a;点击进入 2.linux 压缩命令&#xff1a;tar -zxvf 包名&#xff0c;即可&#xff01; 3.linux配置服务端&#xff08;frps&#xff09; [common] bind_addr0.0.0.0 # frp监听的…

【NLP实战】基于Bert和双向LSTM的情感分类【下篇】

文章目录前言简介第一部分关于pytorch lightning保存模型的机制关于如何读取保存好的模型完善测试代码第二部分第一次训练出的模型的过拟合问题如何解决过拟合后记前言 本文涉及的代码全由博主自己完成&#xff0c;可以随意拿去做参考。如对代码有不懂的地方请联系博主。 博主…

TCP协议与UDP协议

1.TCP协议特点 1.1连接的建立与断开 TCP协议提供的是&#xff1a;面向连接、可靠的、字节流服务。使用TCP协议通信的双发必须先建立连接&#xff0c;然后才能开始数据的读写。双方都必须为该连接分配必要的内核资源&#xff0c;以管理连接的状态和连接上数据的传输。TCP连接是全…

从C语言到C++(第一章_C++入门_下篇)内联函数+auto关键字(C++11)+范围for +nullptr

目录 1. 内联函数 1.1 内联函数的概念 1.2 内联函数的特性 1.3 宏的优缺点和替代方法 2. auto关键字&#xff08;C11&#xff09; 2.1 改版前的auto 2.2 改版后的auto 2.3 auto 的使用场景 2.3.1处理很长的数据类型 2.3.2 auto 与指针结合起来使用&#xff1a; 2.4…

第2章 数据的类型

第2章 数据的类型 文章目录第2章 数据的类型2.2 为什么要进行区分2.3 结构化数据和非结构化数据案例&#xff1a;数据预处理字数/短语数特殊符号文本相对长度文本主题2.4 定量数据和定性数据2.4.1 案例&#xff1a;咖啡店数据2.4.2 案例&#xff1a;世界酒精消费量2.4.3 更深入…

4.18、TCP滑动窗口

4.18、TCP滑动窗口1.滑动窗口的介绍2.滑动窗口通信的例子1.滑动窗口的介绍 滑动窗口&#xff08;Sliding window&#xff09;是一种流量控制技术。早期的网络通信中&#xff0c;通信双方不会考虑网络的拥挤情况直接发送数据。由于大家不知道网络拥塞状况&#xff0c;同时发送数…

客户案例 | 迎接智能化浪潮,传统水厂数字化势在必行

关键发现 客户痛点&#xff1a;传统水厂业务离散&#xff0c;无法实现数据实时同步&#xff0c;为收集和分析处理数据并辅助决策带来障碍。需要智能化管理系统帮助水厂提升管理效率&#xff0c;优化管理流程&#xff0c;实现数字化、智能化的目标。 解决方案&#xff1a;天津腾…

你说你还不会Redis?别怕,今天带你搞定它!

Redis 前言 本文章是我学习过程中&#xff0c;不断总结而成&#xff0c;篇幅较长&#xff0c;可以根据选段阅读。 全篇17000字&#xff0c;图片 十三 张&#xff0c;预计用时1小时。 认识Redis 什么是Redis&#xff1f; 要使用一门技术&#xff0c;首先要知道这门技术是什…

pytorch进阶学习(三):在数据集数量不够时如何进行数据增强

对图片数据增强&#xff0c;可以对图片实现&#xff1a; 1. 尺寸放大缩小 2. 旋转&#xff08;任意角度&#xff0c;如45&#xff0c;90&#xff0c;180&#xff0c;270&#xff09; 3. 翻转&#xff08;水平翻转&#xff0c;垂直翻转&#xff09; 4. 明亮度改变&#xff08;变…

一零五五、mysql8.0高版本数据导入5.6低版本通解

背景 今日想将本机的mysql&#xff08;8.0&#xff09;中的数据库文件导出到远程服务器中的mysql&#xff08;5.6&#xff09;中&#xff0c;刚开始用source 一直报一大串ERROR&#xff0c;由于数据量比较大&#xff0c;那就直接用图形化工具导吧&#xff0c;连接上远程数据库&…