【代码随想录——单调栈】

1.每日温度

在这里插入图片描述

func dailyTemperatures(temperatures []int) []int {stack := list.New()//入栈:stack.PushBack()//出栈:stack.Remove(stack.Back())dp := make([]int, len(temperatures))for i := 0; i < len(temperatures); i++ {if stack.Len() == 0 {stack.PushBack(i)} else {if temperatures[stack.Back().Value.(int)] >= temperatures[i] {stack.PushBack(i)} else {for stack.Len() != 0 && temperatures[stack.Back().Value.(int)] < temperatures[i] {// 设置dpdp[stack.Back().Value.(int)] = i - stack.Back().Value.(int)// 出栈stack.Remove(stack.Back())}stack.PushBack(i)}}}return dp
}

2.下一个更大元素I

在这里插入图片描述

func nextGreaterElement(nums1 []int, nums2 []int) []int {stack := list.New()//入栈:stack.PushBack()//出栈:stack.Remove(stack.Back())dp := make([]int, len(nums2))m := make(map[int]int,0)for i := 0; i < len(nums2); i++ {m[nums2[i]] = iif stack.Len() == 0 {stack.PushBack(i)} else {if nums2[stack.Back().Value.(int)] >= nums2[i] {stack.PushBack(i)} else {for stack.Len() != 0 && nums2[stack.Back().Value.(int)] < nums2[i] {// 设置dpdp[stack.Back().Value.(int)] = i - stack.Back().Value.(int)// 出栈stack.Remove(stack.Back())}stack.PushBack(i)}}}//计算结果ans := make([]int,len(nums1))for i:=0;i<len(nums1);i++{index := m[nums1[i]]hasMoreBigger := dp[index]if hasMoreBigger==0{ans[i]=-1}else{ans[i]=nums2[index+dp[index]]}}return ans
}

3.下一个更大元素II

在这里插入图片描述

func nextGreaterElements(nums []int) []int {stack := list.New()//入栈:stack.PushBack()//出栈:stack.Remove(stack.Back())dp := make([]int,len(nums))for i:=0;i<len(nums);i++{dp[i] = -1}m := make(map[int]int,0)for i:=0;i<len(nums)*2;i++{index := i%len(nums)m[nums[index]] = indexif stack.Len()==0 || nums[stack.Back().Value.(int)] >= nums[index]{stack.PushBack(index)}else{for stack.Len() != 0 && nums[stack.Back().Value.(int)] < nums[index] {// 设置dpdp[stack.Back().Value.(int)] = nums[index]// 出栈stack.Remove(stack.Back())}stack.PushBack(index)}}return dp
}

4. 接雨水

在这里插入图片描述

4.1 暴力解法

记录左边柱子的最高高度 和 右边柱子的最高高度,就可以计算当前位置的雨水面积

func trap(height []int) int {sum := 0for i:=0;i<len(height);i++{// 第一个柱子和最后一个柱子不接雨水if i==0||i==len(height)-1{continue}rHeight := height[i]//记录右边柱子的最高高度lHeight := height[i]//记录左边柱子的最高高度//向右查找最高高度for r:=i+1;r<len(height);r++{if height[r]>rHeight{rHeight = height[r]}}//向左查找最高高度for l:=i-1;l>=0;l--{if height[l]>lHeight{lHeight = height[l]}}h := min(lHeight,rHeight) - height[i]if h>0 {sum += h}}return sum
}

4.2 双指针优化

为了得到两边的最高高度,使用了双指针来遍历,每到一个柱子都向两边遍历一遍,这其实是有重复计算的。我们把每一个位置的左边最高高度记录在一个数组上(maxLeft),右边最高高度记录在一个数组上(maxRight),这样就避免了重复计算。

func trap(height []int) int {sum := 0if len(height)<=2{return sum}maxLeft := make([]int,len(height))maxRight := make([]int,len(height))// 记录每个柱子左边柱子最大高度maxLeft[0] = height[0];for i := 1; i < len(height); i++ {maxLeft[i] = max(height[i], maxLeft[i - 1]);}// 记录每个柱子右边柱子最大高度maxRight[len(height)-1] = height[len(height)-1];for i := len(height)-2; i >=0; i-- {maxRight[i] = max(height[i], maxRight[i + 1]);}// 求和for i:=0; i<len(height);i++{count := min(maxLeft[i],maxRight[i])-height[i]if count > 0{sum += count}}return sum
}

4.3 单调栈

  • 情况一:当前遍历的元素(柱子)高度小于栈顶元素的高度 height[i] < height[st.top()]
    • if (height[i] < height[st.top()]) st.push(i);
  • 情况二:当前遍历的元素(柱子)高度等于栈顶元素的高度 height[i] == height[st.top()]
    • if (height[i] == height[st.top()]) { // 例如 5 5 1 7 这种情况 st.pop(); st.push(i);}
  • 情况三:当前遍历的元素(柱子)高度大于栈顶元素的高度 height[i] > height[st.top()]
    • 计算凹槽的体积
func trap(height []int) int {sum := 0if len(height)<=2{return sum}st := list.New()//入栈:stack.PushBack()//出栈:stack.Remove(stack.Back())st.PushBack(0)for i:=1;i<len(height);i++{if height[i] < height[st.Back().Value.(int)]{//情况1st.PushBack(i)}else if height[i] == height[st.Back().Value.(int)]{//情况2st.Remove(st.Back())st.PushBack(i)}else{//情况3for st.Len()!=0 && height[i]>height[st.Back().Value.(int)]{mid := st.Back().Value.(int)st.Remove(st.Back())if st.Len()!=0{//求高度h := min(height[st.Back().Value.(int)],height[i])-height[mid]//求中间宽度w := i-st.Back().Value.(int)-1sum += h * w}}st.PushBack(i)}}return sum
}

5. 柱状图中最大的矩阵

在这里插入图片描述

5.1 双指针法

这个方法比较通俗易懂。
记录每个柱子左右两边第一个小于该柱子的下标。
但是在leetcode上会超时,该测试用例的特点为所有的height都为一个值,会使得复杂度为n^2

func largestRectangleArea(heights []int) int {minLeftIndex := make([]int, len(heights))minRightIndex := make([]int, len(heights))// 寻找小于当前柱子的第一个柱子的IndexminLeftIndex[0] = -1for i := 1; i < len(heights); i++ {t := i - 1for t >= 0 && heights[t] >= heights[i] {t = t - 1}minLeftIndex[i] = t}minRightIndex[len(heights)-1] = len(heights)for i := len(heights) - 2; i >= 0; i-- {t := i + 1for t <= len(heights)-1 && heights[t] >= heights[i] {t = t + 1}minRightIndex[i] = t}result := 0for i := 0; i < len(heights); i++ {sum := heights[i] * (minRightIndex[i] - minLeftIndex[i] - 1)result = max(sum, result)}return result
}

修改后的版本:

func largestRectangleArea(heights []int) int {minLeftIndex := make([]int, len(heights))minRightIndex := make([]int, len(heights))// 寻找小于当前柱子的第一个柱子的IndexminLeftIndex[0] = -1for i := 1; i < len(heights); i++ {t := i - 1for t >= 0 && heights[t] >= heights[i] {//在特殊情况下避免了大量的重复计算t = minLeftIndex[t]}minLeftIndex[i] = t}minRightIndex[len(heights)-1] = len(heights)for i := len(heights) - 2; i >= 0; i-- {t := i + 1for t <= len(heights)-1 && heights[t] >= heights[i] {//在特殊情况下避免了大量的重复计算t = minRightIndex[t];}minRightIndex[i] = t}result := 0for i := 0; i < len(heights); i++ {sum := heights[i] * (minRightIndex[i] - minLeftIndex[i] - 1)result = max(sum, result)}return result
}

5.2 单调栈法

从栈头(元素从栈头弹出)到栈底的顺序应该是从大到小的顺序!

func largestRectangleArea(heights []int) int {max := 0// 使用切片实现栈stack := make([]int, 0)// 数组头部加入0heights = append([]int{0}, heights...)// 数组尾部加入0heights = append(heights, 0)// 初始化栈,序号从0开始stack = append(stack, 0)for i := 0; i < len(heights); i++ {// 结束循环条件为:当即将入栈元素>top元素,也就是形成非单调递增的趋势for heights[i] < heights[stack[len(stack)-1]] {// mid是topmid := stack[len(stack)-1]// 出栈stack = stack[0 : len(stack)-1]// left是top的下一位元素,i是将要入栈的元素left := stack[len(stack)-1]// 高度x宽度tmp := heights[mid] * (i - left - 1)if tmp > max {max = tmp}}stack = append(stack, i)}return max
}

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

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

相关文章

期末考试后,老师如何高效把成绩发给家长

期末考试终于结束了&#xff0c;老师们是不是感觉松了一口气呢&#xff1f;但是&#xff0c;成绩发布这个环节可不能马虎哦&#xff01;今天&#xff0c;我就来跟大家分享一下如何高效地把成绩发给家长&#xff0c;让这个环节变得既轻松又高效&#xff01; 先把最高效的方式告诉…

ROS2用c++开发参数节点通信

1.创建节点 cd chapt4/chapt4_ws/ ros2 pkg create example_parameters_rclcpp --build-type ament_cmake --dependencies rclcpp --destination-directory src --node-name parameters_basic --maintainer-name "joe" --maintainer-email "1027038527qq.com&…

网安小贴士(1)等级保护

一、定义 等保&#xff0c;即信息安全等级保护&#xff0c;根据信息系统在国家安全、经济建设、社会生活中的重要程度&#xff0c;以及信息系统遭到破坏后对国家安全、社会秩序、公共利益以及公民、法人和其他组织的合法权益的危害程度&#xff0c;将信息系统分为五个不同的安全…

【Python机器学习】模型评估与改进——留一法交叉验证

留一法也是一种常见的交叉验证方法。 我们可以将留一法交叉验证看作是每折只包含单个样本的k折交叉验证。对于每次划分&#xff0c;选择单个数据点作为测试集。这种方法可能非常耗时&#xff0c;特征是对于大型数据&#xff0c;但是小型数据集上有时可以给出更好的估计结果&am…

HarmonyOS Next开发学习手册——显示图片 (Image)

开发者经常需要在应用中显示一些图片&#xff0c;例如&#xff1a;按钮中的icon、网络图片、本地图片等。在应用中显示图片需要使用Image组件实现&#xff0c;Image支持多种图片格式&#xff0c;包括png、jpg、bmp、svg和gif&#xff0c;具体用法请参考 Image 组件。 Image通过…

Python 算法交易实验75 QTV200后续想法梳理

说明 在第一步获取数据源&#xff0c;然后进入Mongo(第一个数据节点)开始&#xff0c;QTV200的数据流体系就开始动了。后续用多少时间完成不太好确定&#xff0c;短则数周&#xff0c;长则数月。毕竟有过第一版实验的基础&#xff0c;应该还是可以做到的。 下面就是天马行空&…

Spring Cloud Sentinel

官网代码案例: 注意&#xff1a; 1. 引入依赖 <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> 2. 配置文件application.yml spring:cloud:sent…

解决Python用xpath爬取不到数据的一个思路

前言 最近在学习Python爬虫的知识&#xff0c;既然眼睛会了难免忍不住要实践一把。 不废话直接上主题 代码不复杂&#xff0c;简单的例子奉上&#xff1a; import requests from lxml import etreecookie 浏览器F12网络请求标头里有 user_agent 浏览器F12网络请求标头里有…

Java+Swing+mysql学生考勤管理系统(高分课程项目)

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、Php、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

系统架构设计师 - 计算机网络(1)

计算机网络 计算机网络TCP/IP 协议簇TCP与UDP ★★★DHCP与DNS ★★★DNS 协议应用DHCP 协议应用 网络规划与设计逻辑设计与物理设计 ★★★★逻辑网络设计物理网路设计 层次化网络设计网络冗余设计 网络存储 ★★网络存储方式磁盘阵列 - Raid 大家好呀&#xff01;我是小笙&am…

【面试系列】信息安全分析师高频面试题及详细解答

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来&#xff1a;详细讲解AIGC的概念、核心技术、…

浅谈定时器之泊松随机定时器

浅谈定时器之泊松随机定时器 “泊松随机定时器”(Poisson Random Timer)&#xff0c;它允许你基于泊松分布来随机化请求之间的延迟时间&#xff0c;这对于模拟具有随机到达率的事件特别有用&#xff0c;如用户访问网站或服务的请求。 泊松分布简介 泊松分布是一种统计与概率…

Golang开发:构建支持并发的网络爬虫

Golang开发&#xff1a;构建支持并发的网络爬虫 随着互联网的快速发展&#xff0c;获取网络数据成为了许多应用场景中的关键需求。网络爬虫作为一种自动化获取网络数据的工具&#xff0c;也因此迅速崛起。而为了应对日益庞大的网络数据&#xff0c;开发支持并发的爬虫成为了必…

操作系统真象还原:进一步完善内核

第12章-进一步完善内核 12.1 Linux系统调用浅析 系统调用就是让用户进程申请操作系统的帮助&#xff0c;让操作系统帮其完成某项工作&#xff0c;也就是相当于用户进程调用了操作系统的功能&#xff0c;因此“系统调用”准确地来说应该被称为“操作系统功能调用”。 Linux 系…

RaysyncCMD-一款及其好用的镭速文件传输工具

在日常的生活及工作流中&#xff0c;文件传输扮演着至关重要的角色&#xff0c;从工作文档、家庭照片到高清视频&#xff0c;每一种数据的迁移都需仰赖高效的文件传输工具。今天&#xff0c;小编今天安利一款性能卓越的文件传输利器——RaysyncCMD。 这是一款专为Windows、Linu…

002-基于Sklearn的机器学习入门:基本概念

本节将继续介绍与机器学习有关的一些基本概念&#xff0c;包括机器学习的分类&#xff0c;性能指标等。同样&#xff0c;如果你对本节内容很熟悉&#xff0c;可直接跳过。 2.1 常见的监督学习方法

智慧渔港:海域感知与岸线监控实施方案(智慧渔港渔船综合管控平台)

文章目录 引言I 技术栈1.1 物理结构图1.2 功能逻辑结构图II 云台(大华)2.1 设备网络SDK运行在Mac平台2.2 WEB无插件开发包III 术语3.1 渔业引言 利用渔船现有的定位导航通讯设备等资源,实现岸线和近岸海域内违法船舶和可疑船舶预警、抓拍、跟踪和行为分析。 在渔船上安装风…

可燃气体报警器定期检测:优化与改进策略的探讨

在现代化的工业环境中&#xff0c;可燃气体报警器的作用日益凸显。它们像是我们生产现场的安全卫士&#xff0c;时刻警惕着可能发生的危险&#xff0c;确保我们的工作环境安全、稳定。 然而&#xff0c;要确保这些“卫士”始终忠诚可靠&#xff0c;定期检测就显得尤为重要。 …

SSL证书中DV通配符与OV通配符证书的全方位对比

SSL证书中的DV通配符证书与OV通配符证书在多个维度上存在显著差异。下面是对这两种证书类型的全方位对比&#xff0c;以便更好地理解它们各自的特性和适用场景。 一、验证流程 DV通配符证书&#xff1a;验证过程集中在域名所有权的确认&#xff0c;通常通过域名DNS解析记录来…

电脑数据丢失该怎么恢复?分享10款数据恢复神器

在数字化时代&#xff0c;数据丢失的问题时有发生&#xff0c;无论是手机&#xff0c;还是电脑&#xff0c;总有误删、格式化等各种原因导致数据丢失。那么当电脑数据丢失后&#xff0c;我们除了从回收站中找回文件&#xff0c;还可以使用哪些方法找回文件呢&#xff1f; 本文将…