算法学习day59

算法学习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.参考资料

[代码随想录]

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Java 并发编程】一文了解线程间有哪些通信方式?

一文了解线程间有哪些通信方式&#xff1f;1. synchronized 内置锁2. volatile 关键字3. 等待/通知机制3.1 等待wait()wait(long)wait(long, int)等待方需遵循如下原则3.2 通知notify()notifyAll()通知方需遵循如下原则notify() 和 notifyAll() 应该用谁&#xff1f;4. 管道输入…

BusterNet网络Python模型实现学习笔记一

实在是无力吐槽了&#xff0c;心力交瘁。作者Github仓库给了错误的 USCISI-CMFD-Small 数据集。自己捣鼓了半天&#xff0c;发现原来是压缩之后数据集&#xff0c;也就是 LMDB 文件格式出错了。实在是误人子弟&#xff0c;自己已经气急败坏了现在… 但是既然论文都花那么长时间…

数据分析之Pandas 基础入门

一、初始Pandas pandas 是数据分析三大件之一&#xff0c;是Python的核心分析库&#xff0c;它提供了快捷、灵活、明确的数据结构&#xff0c;它能够简单、直观、快速的处理各种类型的数据结构。 pandas 支持的数据结构如下&#xff1a; SQL 或Excel 类似的数据有序或无序的…

【学习笔记】unity脚本学习(三)(向量 Vector3)

目录向量复习高中向量基础【数学】向量的四则运算、点积、叉积、正交基叉乘公式叉乘运算定理向量、坐标系点积叉积Vector3 三维向量静态变量变量变量normalized 与 Normalize() 方法静态方法ClampMagnitudeCrossDistanceDotMoveTowards其他变换类似Lerp 在两个点之间进行线性插…

实现一个简单但有趣的AR效果(Web)

有人说:一个人从1岁活到80岁很平凡,但如果从80岁倒着活,那么一半以上的人都可能不凡。 生活没有捷径,我们踩过的坑都成为了生活的经验,这些经验越早知道,你要走的弯路就会越少。

MySQL 库操作

目录 创建数据库 语法 案例 字符集和校验规则&#xff08;建数据库/建表用&#xff09; 查看系统默认字符集以及校验规则 db.opt 更改 查看数据库支持的字符集 查看数据库支持的字符集校验规则 校验规则对数据库的影响 排升序 操纵数据库 查看数据库 显示创建语…

洛谷P2822:组合数问题 ←(帕斯卡法则+取模+前缀和)

【题目来源】https://www.luogu.com.cn/problem/P2822https://www.acwing.com/problem/content/525/【题目描述】 组合数​表示的是从n个物品中选出m个物品的方案数。举个例子&#xff1a;从(1,2,3)三个物品中选择两个物品可以有(1,2)&#xff0c;(1,3)&#xff0c;(2,3) 这三种…

MySQl_1

一.相关概念 数据库&#xff1a;存放数据的仓库 数据库管理系统&#xff1a;操作和管理数据库的大型软件&#xff0c;如mysql SQL&#xff1a;一种操作 关系型数据库管理系统的语言&#xff0c;定义了一套操作关系型数据库管理系统的统一标准。 关系型数据库&#xff1a;有多…

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

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

PyTorch深度学习实战 | 基于ResNet的人脸关键点检测

人脸关键点检测指的是用于标定人脸五官和轮廓位置的一系列特征点的检测&#xff0c;是对于人脸形状的稀疏表示。关键点的精确定位可以为后续应用提供十分丰富的信息。因此&#xff0c;人脸关键点检测是人脸分析领域的基础技术之一。许多应用场景(如人脸识别、人脸三维重塑、表情…

Mariadb10.5基于同服务器多实例主从配置

本次部署环境&#xff1a;Centos8stream 本次部署mariadb版本&#xff1a; mariadb:10.5 本次部署方式&#xff1a;rpm包直接安装&#xff0c;并通过systemd直接托管 可以参考 /usr/lib/systemd/system/mariadb.service 该文件 # Multi instance version of mariadb. For i…

python wannier90 基于wannier90的*_hr.dat文件选取截断hopping绘制能带图

我们知道wannier90可以根据选取TMDs的轨道信息生成详细的hopping energy *_hr.dat文件&#xff0c;选取所有的hopping绘制起来的时候比较简单&#xff0c;但是我们发现取几圈的近似hopping也可以将band表示出来&#xff0c;类似的思想有Pybinding的三带近似&#xff08;DOI: 10…

初中级Android工程师如何快速成长寻求突破

前言 写这篇文章的初衷是看到很多同学在一家公司工作了三五年&#xff0c;因为技术没有得到提升而随着年龄的增长导致不敢提出涨薪和跳槽找工作。希望这篇文章能够给这些还是初中级Android工程师的朋友一些启发。 快速成长 我们在向领导提出加薪申请或者是准备跳槽到更大的平…

【论文阅读】On clustering using random walks

《On clustering using random walks》阅读笔记 1. 问题建模 1.1 问题描述 let G(V,E,ω)G(V,E,\omega)G(V,E,ω) be a weighted graph, VVV is the set of nodes, EEE is the edge between nodes in VVV, ω\omegaω is the function ω&#xff1a;E→Rn\omega&#xff1a…

初识掌控板2.0、官方拓展板和配套编程软件mpython

不是广告&#xff01;&#xff01;不是广告&#xff01;&#xff01; 一、掌控板2.0概览 掌控板又名掌上联网计算机&#xff0c;是一款为青少年学习Python编程和创意制造&#xff0c;特别是物联网应用而设计的开源硬件。内置microPython开源嵌入式Python运行环境&#xff0c;可…

快排非递归 归并排序

递归深度太深会栈溢出 程序是对的&#xff0c;但是递归个10000层就是栈溢出 int fun(int n) {if (n < 1){return n;}return fun(n - 1) n; }所以需要非递归来搞快排和归并&#xff0c;在效率方面没什么影响&#xff0c;只是解决递归深度太深的栈溢出问题 有的能直接改&am…

快速尝鲜Oracle 23c免费开发者版,惊喜多多

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&am…

Matplotlib数据可视化

Matplotlib是⼀个Python 2D&#xff0c;3D绘图库&#xff0c;它以多种硬拷⻉格式和跨平台的交互式环境⽣成出版物质量的图形。 MatplotlibMatplotlib中文网、Matplotlib官方中文文档。https://www.matplotlib.org.cn/ 1.模块导⼊ import matplotlib.pyplot as plt #使⽤py…

代码随想录算法训练营第六天|242 有效的字母异位词 349 两个数组的交集 202 快乐数 1 两数之和

文章目录哈希表242 有效的字母异位词思路代码总结349 两个数组的交集思路代码总结202 快乐数思路代码总结1 两数之和思路代码总结哈希表 哈希碰撞&#xff1a;拉链法&#xff08;链表&#xff09;线性探测法&#xff08;顺序向后&#xff09; std::unordered_map, std::unorde…

nacos集群搭建

1.本实验使用四台centos7主机&#xff0c;均关闭防火墙和selinux服务 2.数据库选择 不推荐使用nacos自带的嵌入式数据库derby&#xff0c;因为需要保证数据的一致性&#xff0c;本集群使用mysql数据库&#xff0c;因为nacos自带的嵌入式数据库derby是每个nacos服务一个数据库…