代码随想录算法训练营 --- 第五十九天

今天同样是单调栈,第二题很重要。

第一题:

简介:

本题可以说和上一题很是相似,只是有一点不同,数组是循环的。本题有两种巧妙地解法,都不难。

第一种方法(也是第一个想出来的方法):

拼接数组,我们将两个相同的nums数组进行拼接这样我们就可以保证第一个nums数组进行了循环的遍历。此方法容易相处但是有很多弊端:例如浪费空间很多,也做了很多多余的操作,我们拼接数组后,还要剪切数组等等。

代码实现:
vector<int> nextGreaterElements(vector<int>& nums) {stack<int> str;vector<int> path(nums.size()*2,0);vector<int> result(nums.size()*2,-1);str.push(0);int k=0;for(int i=0;i<nums.size()*2;i++){if(k==nums.size()) k=0;path[i] = nums[k];k++;}for(int i=1;i<path.size();i++){if(path[i]>path[str.top()]){while(!str.empty()&&path[i]>path[str.top()]){result[str.top()] = path[i];str.pop();}str.push(i);}else if(path[i] == path[str.top()]){str.push(i);}else{str.push(i);}}for(int i=0;i<nums.size();i++){result.pop_back();}return result;}
第二种方法(很巧妙的实现了循环遍历数组):

此种方法我们通过 [i%nums.size()]来实现我们重复遍历数组的目的。

代码实现: 
 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;}

第二题:

简介:

本题是面试中考的概率很高的一题。

本题共有三种方法

暴力破解法

暴力法的重点在于如何求出单列的水的体积例如:

列4 左侧最高的柱子是列3,高度为2(以下用lHeight表示)。

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

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

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

列4的雨水高度求出来了,宽度为1,相乘就是列4的雨水体积了。

此时求出了列4的雨水体积。

我们遍历每列然后将结果相加也就是最后的答案。

时间复杂度为O(n)

代码实现:
 int trap(vector<int>& height) {int sum = 0;for (int i = 0; i < height.size(); i++) {// 第一个柱子和最后一个柱子不接雨水if (i == 0 || i == height.size() - 1) continue;int rHeight = height[i]; // 记录右边柱子的最高高度int lHeight = height[i]; // 记录左边柱子的最高高度for (int r = i + 1; r < 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;}return sum;}
双指针法

思路与暴力解法一样,只是我们在代码实现上有所不同,我们通过两个数组将左边柱子最大高度和右边柱子最大高度都记录下来。然后我们在遍历时就省下了很多时间。时间复杂度O(n)

代码实现:
  int trap(vector<int>& height) {if (height.size() <= 2) return 0;vector<int> maxLeft(height.size(), 0);vector<int> maxRight(height.size(), 0);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;}
单调栈法

单调栈发与前两个解法不同,前两个解法是按列来计算,此解法为按行来计算。后面便利的过程建议去跟卡哥的视频走一趟就明白了,或者自己模拟过程。

代码实现:
  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()]) { // 注意这里是whileint 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.mzph.cn/news/207894.shtml

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

相关文章

创建自定义Docker镜像:一步步指南

当创建自定义Docker镜像时&#xff0c;Dockerfile是关键的一环。这篇博客将详细介绍如何编写一个Dockerfile&#xff0c;其中包含创建自定义应用程序所需的步骤和示例。让我们开始吧&#xff1a; 创建自定义Docker镜像&#xff1a;一步步指南 1. 了解Dockerfile Dockerfile是…

我的acer电脑U盘装系统前BIOS设置及装系统过程中的操作

1、开机长按F2进入BIOS设置 2、使能F12 3、调整boot顺序&#xff0c;使USB启动的优先级最高 4、按F10保存退出 5、插入U盘开机&#xff0c;boot选择界面无需操作&#xff0c;等待几秒&#xff0c;默认进入U盘系统 由于既使能了F12&#xff0c;又将U盘的优先级进调整到了最高&…

OpenVINS学习1——数据集配置与运行

前言 OpenVINS是基于MSCKF的开源VIO算法&#xff0c;有非常详细的官网文档可以学习使用&#xff0c;将来一段时间的主要实践工作&#xff0c;就是深度掌握这份开源代码。 https://docs.openvins.com/ 一、环境配置与Euroc数据集运行 我的环境是Ubuntu20.04&#xff0c;ROS1&a…

vue3中实现el-tree通过ctrl或shift批量选择节点并高亮展示

一、看效果&#xff1a; 按住ctrl键实现单个多选 按住shift实现区间范围多选 二、代码&#xff1a; vue页面 <template><el-treeclass"w100%":data"$.treeData"ref"treeTab…

Unity中Batching优化的静态合批

文章目录 前言一、静态合批的规则1、模型使用同一个材质2、勾选静态合批3、对于静态合批后的Mesh顶点总数&#xff0c;不超过2^16^即可以使用同一批次&#xff0c;超过则会开启一个新的批次4、对与使用同一材质的不同模型间&#xff0c;纹理贴图的问题&#xff0c;我们可以通过…

数据可视化工具选择:功能、易用性与安全性

作为一名数据可视化大屏设计师&#xff0c;我深知选择一款合适的数据可视化工具对于提高工作效率和呈现效果的重要性。下面&#xff0c;我将从真正对我们数据可视化大屏设计师有用的角度为大家介绍选择数据可视化工具的一些必要条件和要求。 1. 功能强大与灵活定制 首先&…

高并发场景下的httpClient使用优化技巧

1. 背景 我们有个业务&#xff0c;会调用其他部门提供的一个基于http的服务&#xff0c;日调用量在千万级别。使用了httpclient来完成业务。之前因为qps上不去&#xff0c;就看了一下业务代码&#xff0c;并做了一些优化&#xff0c;记录在这里。 先对比前后&#xff1a;优化…

如何做好口译服务,同传和交传哪个服务好

随着中国经济的蓬勃发展和综合实力的不断增强&#xff0c;中国与世界各国的交流也日益频繁。口译作为对外交流的桥梁与纽带&#xff0c;需求量与日俱增&#xff0c;其重要性不言而喻。那么&#xff0c;如何做好口译服务呢&#xff1f;是同传还是交传更好呢&#xff1f; 业内专家…

渗透测试工具AWVS的全面解析

在当今的数字化时代&#xff0c;网络安全已经成为了企业和个人必须关注的重要问题。为了确保网络的安全&#xff0c;我们需要使用各种工具和技术进行检测和防护。其中&#xff0c;渗透测试是一种非常重要的方法&#xff0c;它可以帮助我们发现网络中的安全漏洞&#xff0c;并采…

机器人纯阻抗控制接触刚性环境

问题描述 在机器人学中&#xff0c;阻抗控制是一种常用的控制策略&#xff0c;用于管理机器人在与环境交互时的运动和力。阻抗控制背后的关键概念是将环境视为导纳&#xff0c;而将机器人视为阻抗。 纯阻抗控制接触刚性环境时&#xff0c;机器人的行为方式主要受其阻抗参数的…

表单小程序作用体现在哪

表单的用途非常广泛&#xff0c;它是线上收集信息或用户预约/需求服务的重要方式&#xff0c;对商家来说如今线上平台非常多&#xff0c;生意开展的形式也越来越多&#xff0c;比如常见的预约、报名、收款、产品支付等都可以通过表单实现。 接下来啊让我们看看通过【雨科】平台…

家用智能门锁——智能指纹锁方案

智能指纹锁产品功能&#xff1a; 1&#xff1a;指纹识别技术&#xff1a;光学传感器、半导体传感器或超声波传感器等。 2&#xff1a;指纹容量&#xff1a;智能指纹锁可以存储的指纹数量&#xff0c;通常在几十到几百个指纹之间。 3&#xff1a;解锁时间&#xff1a;指纹识别和…

【力扣100】8.找到字符串中所有字母异位词

添加链接描述 class Solution:def findAnagrams(self, s: str, p: str) -> List[int]:sildingstrresult[]p.join(sorted(p))for i in range(len(s)):if len(sildingstr)<len(p):sildingstrsildingstrs[i]# print(sildingstr)if len(sildingstr)len(p):sort_sildingstr.j…

Android开发常用工具类集合

目录 DownloadGradleAPIsActivity 相关 -> ActivityUtils.java -> DemoAdaptScreen 相关 -> AdaptScreenUtils.java -> DemoApp 相关 -> AppUtils.java -> Demo栏相关 -> BarUtils.java -> Demo亮度相关 -> BrightnessUtils.java -> DemoBus 相关…

身份认证技术

身份认证是对系统的用户进行有效性、真实性验证。 1&#xff0e;口令认证方式 使用口令认证方式&#xff0c;用户必须具有一个唯一的系统标识&#xff0c;并且保证口令在系统的使用和存储过程中是安全的&#xff0c;同时口令在传输过程中不能被窃取、替换。另外特别要注意的是在…

解决:During handling of the above exception, another exception occurred

解决&#xff1a;During handling of the above exception, another exception occurred 文章目录 解决&#xff1a;During handling of the above exception, another exception occurred背景报错问题报错翻译报错位置代码报错原因解决方法参考内容&#xff1a;今天的分享就到…

numpy数据读取保存及速度测试

目录 数据保存及读取 速度比对测试 数据保存及读取 代码示例&#xff1a; # 导入必要的库 import numpy as np # 生成测试数据 arr_disk np.arange(8) # 打印生成能的数据 print(arr_disk) # numpy保存数据到本地 np.save("arr_disk", arr_disk) # 加载本地数据…

排序算法-插入/希尔排序

1 插入排序 1.1基本思想&#xff1a; 直接插入排序是一种简单的插入排序法&#xff0c;其基本思想是&#xff1a;把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为止&#xff0c;得到一个新的有序序列 。 1.2直…

CentOS7.0 下rpm安装MySQL5.5.60

下载 下载路径: MySQL :: Download MySQL Community Server -->looking for the latest GA version-->5.5.60 此压缩包中有多个rpm包 有四个不是必须的,只需安装这三个 MySQL-server-5.5.60-1.el6.x86_64 MySQL-devel-5.5.60-1.el6.x86_64 MySQL-client-5.5.60-1.el6.x8…

pymysql insert dataframe 遇到 nan 值

def get_db_conn():"""MYSQL连接"""host Config.MYSQL["host"]pwd Config.MYSQL["pwd"]user Config.MYSQL["user"]port Config.MYSQL["port"]database Config.MYSQL["database"]conn p…