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

文档讲解:代码随想录

视频讲解:代码随想录B站账号

状态:看了视频题解和文章解析后做出来了

503.下一个更大元素II

class Solution:def nextGreaterElements(self, nums: List[int]) -> List[int]:res = [-1] * len(nums)stack = []for i in range(len(nums)*2):while len(stack) > 0 and nums[i%len(nums)] > nums[stack[-1]]:res[stack[-1]] = nums[i%len(nums)]stack.pop()stack.append(i%len(nums))return res
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

这道题和每日温度非常相似,只不过这次的数组是头接尾的,也就是说后面的元素也可以视前面的元素为比自己大的元素。

第一种方法是复制一个nums数组然后和原数组拼接在一起,最后把res resize成原来的大小,虽然最后的resize复杂度为O(1),但扩充数组的复杂度就是O(n)了,不太值得。

比较好的一种方式是循环这个数组两遍,所以在for循环的range里,使用的是len(nums) * 2。

在提取当前元素的值时,需要用到取模操作,取nums的长度,也就是说假设nums长度为5,那么循环到6的时候,下标为1。这个取模操作要应用到所有和 i 相关的操作中防止逾越index问题。

42. 接雨水 

暴力双指针

class Solution:def trap(self, height: List[int]) -> int:res = 0for i in range(1, len(height)-1):left_bar, right_bar = height[i], height[i]for j in range(i+1, len(height)):if height[j] > right_bar:right_bar = height[j]for z in range(i-1, -1, -1):if height[z] > left_bar:left_bar = height[z]h = min(right_bar, left_bar) - height[i]res += hreturn res
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(n)

可以从行和列接雨水,从列接雨水的逻辑比较清晰,因为宽度一定是1所以只需要计算高度就行了。

想要计算一列能够接多少雨水,和木桶问题很像,取决于两边较矮的那个边的长度。

所以对于每一列,只需要首先将left_bar,right_bar初始化为当前的高度,然后依次向左和向右遍历,只要找到比左bar和右bar更高的bar就更新。

最后计算的时候,取两者的较小然后减去当前的高度 h = min(right_bar, left_bar) - height[i]。

卡哥的代码里最后还加了个判断h大于0的if,这个没必要哈因为left_bar和right_bar只有比height[i]大的时候才更新,没找到就是它自己,所以最差情况也是0,不可能小于0。

双指针优化

class Solution:def trap(self, height):if len(height) <= 2:return 0size = len(height)max_left = [0] * sizemax_right = [0] * size# Record the maximum height to the left of each barmax_left[0] = height[0]for i in range(1, size):max_left[i] = max(height[i], max_left[i - 1])# Record the maximum height to the right of each barmax_right[size - 1] = height[size - 1]for i in range(size - 2, -1, -1):max_right[i] = max(height[i], max_right[i + 1])# Calculate the total trapped watertotal_water = 0for i in range(size):water_at_bar = min(max_left[i], max_right[i]) - height[i]total_water += water_at_barreturn total_water
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

在暴力方法中,我们每到一个位置都要计算它左边和右边的最高bar,这里就会涉及很多重复计算。如果我们把每个点的左右最高bar首先计算出来保存在两个数组中,在循环过程中使用这个数组中的值就避免了重复运算。

单调栈

class Solution:def trap(self, height: List[int]) -> int:stack = [0]result = 0for i in range(1, len(height)):while stack and height[i] > height[stack[-1]]:mid_height = stack.pop()if stack:# 雨水高度是 min(凹槽左侧高度, 凹槽右侧高度) - 凹槽底部高度h = min(height[stack[-1]], height[i]) - height[mid_height]# 雨水宽度是 凹槽右侧的下标 - 凹槽左侧的下标 - 1w = i - stack[-1] - 1# 累计总雨水体积result += h * wstack.append(i)return result
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

首先明确单调栈是按行来接雨水的:

然后确定单调栈是递增还是递减,这道题中是从栈头到栈尾单调递增。因为如果遇到了比前一个高的元素,说明遇到了桶的右bar,这时候就要pop来进行操作了。

分三种情况:

1. 如果当前元素小于前一个元素,直接入栈并保持单调递增。

2. 如果当前元素等于前一个元素,5543的情况,我们在后续计算雨水体积的时候,肯定也是用右侧的两个5的第二个5来计算,所以先pop再append。

3. 如果当前元素大于前一个元素,开始操作了。

- 首先pop获取上一个元素的高度,赋值给mid变量

- 计算高度,高度为当前元素 i 和当前栈头,也就是 i - 2的高度的较小值

- 计算宽度,宽度就是当前元素下标 i 减去栈头,再加1。假设当前元素下标为5,栈头为3,那么

5 - 3 - 1 = 1,宽度也只是1,符合题意。

- 将长乘以宽的体积计入结果变量res中。

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

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

相关文章

06 # 枚举类型

一个角色判断例子 function initByRole(role) {if (role 1 || role 2) {// do sth} else if (role 3 || role 4) {// do sth} else if (role 5) {// do sth} else {// do sth} }上面的代码存在的问题&#xff1a; 可读性差&#xff1a;很难记住数字的含义可维护性差&…

基于单片机智能液位水位监测控制系统

**单片机设计介绍&#xff0c; 基于单片机智能液位水位监测控制系统 文章目录 一 概要特点应用场景工作原理实现方式 系统功能实时监测控制调节报警功能数据记录与分析 总结 二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 ## 系统介绍 基于单片机…

私域数字化建设:解锁企业融资新引擎

私域数字化建设对于增加企业融资能力的机遇是十分重要的&#xff0c;随着数字化经济的快速发展和数据技术的不断进步&#xff0c;企业需要正确认识到数据资产的重要性和私域数字化建设在提升融资能力等方面所带来的机遇。 近期&#xff0c;财政部发布了《企业数据资源相关会计…

CONTROLLING VISION-LANGUAGE MODELS FOR MULTI-TASK IMAGE RESTORATION

CONTROLLING VISION-LANGUAGE MODELS FOR MULTI-TASK IMAGE RESTORATION (Paper reading) Ziwei Luo, Uppsala University, ICLR under review(6663), Cited:None, Stars: 350, Code, Paper. 1. 前言 像CLIP这样的视觉语言模型已经显示出对零样本或无标签预测的各种下游任务…

深度学习毕设项目 深度学习 python opencv 动物识别与检测

文章目录 0 前言1 深度学习实现动物识别与检测2 卷积神经网络2.1卷积层2.2 池化层2.3 激活函数2.4 全连接层2.5 使用tensorflow中keras模块实现卷积神经网络 3 YOLOV53.1 网络架构图3.2 输入端3.3 基准网络3.4 Neck网络3.5 Head输出层 4 数据集准备4.1 数据标注简介4.2 数据保存…

F. Magic Will Save the World

首先积攒了能量打了怪再积攒是没有意义的&#xff0c;可以直接积攒好&#xff0c;然后一次性进行攻击 那么怎么进行攻击了&#xff1f;可以尽量的多选怪物使用水魔法攻击剩余的再用火魔法进行攻击&#xff0c; 也就是只要存在合法的体积&#xff08;即装入背包的怪物的体积之…

geoserver根据数据字段动态设置样式

一、数据展示&#xff1a; 二、样式设置 <?xml version"1.0" encoding"UTF-8"?> <StyledLayerDescriptor version"1.0.0" xsi:schemaLocation"http://www.opengis.net/sld StyledLayerDescriptor.xsd" xmlns"http://…

Linux下Docker 离线安装详细步骤,亲测成功

1.离线原因&#xff1a;公司新创不能使用开元linux&#xff0c;使用了一个变种centOS&#xff0c;致使yum被禁 2.步骤&#xff1a; 2.1 下载docker tar包&#xff0c;下载地址&#xff1a;Index of linux/https://download.docker.com/linux/ 2.2 新建自己的软件目录&am…

智能AI问答系统ChatGPT网站系统源码+Midjourney绘画+支持GPT-4-Turbo模型+支持GPT-4图片理解能力

一、AI创作系统 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI…

解决Unable to preventDefault inside passive event listener invocation.报错

报错信息&#xff1a; 这个报错大致说的是&#xff1a;无法在被动事件侦听器调用中防止Default 查了其他博主的解决办法&#xff1a;比如&#xff1a; 1、声明事件监听的时候设置为主动事件监听&#xff1a; window.addEventListener(‘touchmove’, handler, { passive: fal…

基于傅里叶变换的运动模糊图像恢复算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1、傅里叶变换与图像恢复 4.2、基于傅里叶变换的运动模糊图像恢复算法原理 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 %获取角度 img…

P8649 [蓝桥杯 2017 省 B] k 倍区间(前缀和+优化(桶分类))

分析&#xff1a; &#xff08;1&#xff09;任意连续子序列可用两个前缀和的差来表示 &#xff08;2&#xff09;判断该子序列是否为k的倍数 p1-p2 模 0 (mod k) 等价于&#xff1a;前缀和模 k 是否同余 &#xff08;3&#xff09;同余的任意两前缀和组合的序列均满足…