【八十五】【算法分析与设计】单调栈的全新版本,两个循环维护左小于和右小于信息,84. 柱状图中最大的矩形,85. 最大矩形

84. 柱状图中最大的矩形

给定 n 个非负整数,用来表示柱状图中各个柱子的高度。每个柱子彼此相邻,且宽度为 1 。

求在该柱状图中,能够勾勒出来的矩形的最大面积。

示例 1:

输入:heights = [2,1,5,6,2,3] 输出:10 解释:最大的矩形为图中红色区域,面积为 10

示例 2:

输入: heights = [2,4] 输出: 4

提示:

  • 1 <= heights.length <=10(5)

  • 0 <= heights[i] <= 10(4)

1.

思路就是以每一个位置的柱状图的高度作为矩形的高,然后看以这个高能够扩多长的底,计算这个情况下的面积.

问题被划分为几个小的部分,以每一个高度为高去计算.

2.

单调栈存储左小于,右小于.

老旧的单调栈写法是在元素出栈的时候维护数据.

但是发现这样特别浪费内存,有的时候还需要给栈开辟二维空间处理相同的数据.

这种做法实在是太低效了,并且在这道题目的提交结果居然超出了题目的内存.

3.

全新的版本,只用一个单独的栈就可以完成重复元素或者不重复元素.

首先我们需要确定我们的目的是什么,是填写信息每一个元素左小于,右小于的信息.

老旧版本是在出栈的时候维护信息,全新版本是在入栈的时候维护信息.

每一个元素入栈的时候,维护栈内单调性,然后维护入栈元素左小于或者右小于信息.

对于每一个入栈元素,栈内一定是单调性,此时一定可以找到左小于或者右小于.

老旧版本

 
class Solution {
public:vector<int> arr;int n;int ret;using p = pair<int, int>;vector<p> p_m;vector<vector<int>> st;void init() {n = arr.size();p_m.clear(), p_m.resize(n);}void solve() {int i = 0;while (1) {if (i >= n)break;if (st.empty())st.push_back({i});else {auto top = st.back();while (1) {if (arr[i] >= arr[top[0]])break;st.pop_back();for (auto& x : top) {p_m[x].second = i;p_m[x].first = st.empty() ? -1 : st.back().back();}if (st.empty())break;elsetop = st.back();}if (st.empty())st.push_back({i});else {if (arr[st.back()[0]] == arr[i])st.back().push_back(i);elsest.push_back({i});}}i++;}while(1){if(st.empty())break;auto top=st.back();st.pop_back();for(auto& x:top){p_m[x].second=n;p_m[x].first=st.empty()?-1:st.back().back();}}for(int i=0;i<n;i++){ret=max(ret,arr[i]*(p_m[i].second-p_m[i].first-1));}}int largestRectangleArea(vector<int>& _heights) {arr = _heights;init(), solve();return ret;}
};

全新版本

 
class Solution {
public:vector<int> arr;//下标-元素int n;//元素的个数int ret;//记录结果信息using p = pair<int, int>;vector<p> p_m;//记录每一个元素左小于,右小于的信息vector<int> st;//vector模拟栈void init() {n = arr.size();p_m.clear(), p_m.resize(n);}void solve() {//首先维护每一个元素的左小于的信息for (int i = 0; i < n; i++) {while (1) {//维护栈内单调性,严格的小到大if (st.empty())break;if (arr[st.back()] < arr[i])break;st.pop_back();//出栈,因为此时他们都不可能再作为某元素的左小于了.}//维护入栈元素的左小于信息p_m[i].first = st.empty() ? -1 : st.back();st.push_back(i);//入栈}st.clear();//栈清空//维护所有元素的右小于信息//此时必须是从后往前填写,因为对于j位置我需要找右小于,那么右边所有元素需要入栈并且栈保持单调for (int i = n - 1; i >= 0; i--) {while (1) {if (st.empty())break;if (arr[st.back()] < arr[i])break;st.pop_back();}p_m[i].second = st.empty() ? n : st.back();//维护右小于信息st.push_back(i);}for (int i = 0; i < n; i++) {ret = max(ret, arr[i] * (p_m[i].second - p_m[i].first - 1));}}int largestRectangleArea(vector<int>& _heights) {arr = _heights;init(), solve();return ret;}
};

85. 最大矩形

给定一个仅包含 01 、大小为 rows x cols 的二维二进制矩阵,找出只包含 1 的最大矩形,并返回其面积。

示例 1:

 

class Solution { public: vector<int> arr; //下标-元素 int n; //元素的个数 int ret; //记录结果信息 using p = pair<int, int>; vector<p> p_m; //记录每一个元素左小于,右小于的信息 vector<int> st; //vector模拟栈 void init() { n = arr.size(); p_m.clear(), p_m.resize(n); } void solve() { //首先维护每一个元素的左小于的信息 for (int i = 0; i < n; i++) { while (1) { //维护栈内单调性,严格的小到大 if (st.empty()) break; if (arr[st.back()] < arr[i]) break; st.pop_back(); //出栈,因为此时他们都不可能再作为某元素的左小于了. } //维护入栈元素的左小于信息 p_m[i].first = st.empty() ? -1 : st.back(); st.push_back(i); //入栈 } st.clear(); //栈清空 //维护所有元素的右小于信息 //此时必须是从后往前填写,因为对于j位置我需要找右小于,那么右边所有元素需要入栈并且栈保持单调 for (int i = n - 1; i >= 0; i--) { while (1) { if (st.empty()) break; if (arr[st.back()] < arr[i]) break; st.pop_back(); } p_m[i].second = st.empty() ? n : st.back(); //维护右小于信息 st.push_back(i); } for (int i = 0; i < n; i++) { ret = max(ret, arr[i] * (p_m[i].second - p_m[i].first - 1)); } } int largestRectangleArea(vector<int>& _heights) { arr = _heights; init(), solve(); return ret; } };

输入:matrix = [["1","0","1","0","0"],["1","0","1","1","1"],["1","1","1","1","1"],["1","0","0","1","0"]] 输出:6 解释:最大矩形如上图所示。

示例 2:

输入:matrix = [["0"]] 输出:0

示例 3:

输入:matrix = [["1"]] 输出:1

提示:

  • rows == matrix.length

  • cols == matrix[0].length

  • 1 <= row, cols <= 200

  • matrix[i][j]'0''1'

1.

思路是每一行看作是柱状图的开始,那么题目完全转化为84. 柱状图中最大的矩形.

用dp记录每一个位置的柱状图高度.

每一行都计算一次,ret记录所有情况的最大值即可.

2.

入栈的时候维护信息.

一个循环维护左信息,一个循环维护右信息.

 
class Solution {
public:vector<vector<char>> arr;//arr表示矩形原始数据int row, col;//row和col表示矩形的行和列数int ret;//ret记录结果数据vector<vector<int>> dp;//dp记录所有位置的柱状图高度vector<vector<int>> p_min;//存储每一行的柱状图的左小于右小于信息vector<int> st;//模拟栈void init() {row = arr.size(), col = arr[0].size();dp.clear(), dp.resize(row, vector<int>(col));//计算dp值for (int j = 0; j < col; j++) {for (int i = 0; i < row; i++) {if (arr[i][j] == '1')dp[i][j] = 1 + (i - 1 >= 0 ? dp[i - 1][j] : 0);elsedp[i][j] = 0;}}p_min.clear(), p_min.resize(col, { 0, 0 });//用{}大括号初始化vector,长度小的时候很方便for (int i = 0; i < row; i++) {for (int j = 0; j < col; j++) {cout << dp[i][j] << " ";}cout << endl;}//看一下dp值有没有计算计算错误}void solve() {//正式开始解题for (int i = 0; i < row; i++) {//首先遍历每一行,表示每一个柱状图p_min.clear(), p_min.resize(col, { 0, 0 });st.clear();//初始化左小于右小于信息//初始化栈for (int j = 0; j < col; j++) {//先维护当前行的左小于信息while (1) {if (st.empty())break;if (dp[i][j] > dp[i][st.back()])break;st.pop_back();}p_min[j][0] = st.empty() ? -1 : st.back();//维护当前j位置左小于信息st.push_back(j);//入栈}st.clear();//栈清空//维护右小于信息for (int j = col - 1; j >= 0; j--) {while (1) {if (st.empty())break;if (dp[i][j] > dp[i][st.back()])break;st.pop_back();}p_min[j][1] = st.empty() ? col : st.back();st.push_back(j);}//此时完成当前行的左小于右小于信息维护//计算此时可能的矩形面积for (int j = 0; j < col; j++) {ret = max(ret, (p_min[j][1] - p_min[j][0] - 1) * dp[i][j]);}for (int j = 0; j < col; j++) {cout << p_min[j][0] << " " << p_min[j][1] << " ";}cout << endl;//打印看一下有没有问题}}int maximalRectangle(vector<vector<char>>& _matrix) {ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);arr = _matrix;init();solve();return ret;}
};

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。

同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。

谢谢您的支持,期待与您在下一篇文章中再次相遇!

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

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

相关文章

nginx开启局域网https访问

需求 调试webRTC 功能,需要在局域网搭建https发给我协议; 实现 环境 局域网已部署有nginx; 部署可参考专栏文章 已安装Openssl 未安装可以执行 sudo yum install openssl 这个命令进行安装 生成证书和私钥 生成私钥:打开命令提示符或终端窗口,执行以下命令以生成私钥文件…

日本站群服务器的优点以及适合该服务器的业务类型?

日本站群服务器的优点以及适合该服务器的业务类型? 日本站群服务器是指位于日本地区的多个网站共享同一台服务器的架构。这种服务器架构有着诸多优点&#xff0c;使其成为许多企业和网站管理员的首选。以下是日本站群服务器的优点以及适合该服务器的业务类型的分析&#xff1…

企业怎样进行项目管理?

在当今快节奏的商业环境中&#xff0c;企业要想保持竞争力&#xff0c;有效的项目管理是关键。项目管理不仅涉及到规划、执行和监控&#xff0c;还包括团队协作、资源分配和风险管理等多个方面。zz-plan 作为一款集多种功能于一体的在线甘特图协作软件&#xff0c;为企业项目管…

【小笔记】问答系统可视化实现的三种方式

下面三种方式都是基于Python的哈&#xff0c;从简单到复杂。 方式一&#xff1a;命令行交互问答 优点&#xff1a;原始简单直接 方式二&#xff1a;使用Python可视化框架 优点&#xff1a;无需学习前端技术栈即可搭建一个web。 streamlit&#xff1a;⭐️⭐️⭐️⭐️gra…

MySQL——变量的定义与使用

新建链接&#xff0c;自带world数据库&#xff0c;里面自带city表格。 DQL # MySQL变量的定义与使用 #1、不允许数字作为开头 #2、只能用_或$符号&#xff0c;不允许使用其他符号 #3、不允许使用关键字或保留字 set userName小可爱; select userName; #标识符只影响当前查询#…

Web地理空间引擎

Web地理空间引擎是指用于在Web上创建和显示地理空间信息的软件平台。它们通常提供一组API和工具&#xff0c;用于加载、可视化和分析地理空间数据。Web地理空间引擎被广泛应用于各种应用&#xff0c;例如地图、导航、位置服务、游戏和模拟等。北京木奇移动技术有限公司&#xf…

24数维杯ABC题思路已更新!!!!

24数维杯A题保姆级思路&#xff0b;配套代码&#xff0b;后续参考论文 简单麦麦https://www.jdmm.cc/file/2710639/ 24数维杯B题保姆级思路&#xff0b;可执行代码&#xff0b;后续参考论文 简单麦麦https://www.jdmm.cc/file/2710640/ 24数维杯C题保姆级思路&#xff0b;可执…

四选一多路选择器

描述 制作一个四选一的多路选择器&#xff0c;要求输出定义上为线网类型。状态转移&#xff1a; d0 11 d1 10 d2 01 d3 00 信号示意图如下所示&#xff1a; 波形示意图&#xff1a; 输入描述&#xff1a; 输入信号 d1,d2,d3,d4 sel 类型 wire 输出描述…

宝塔面板如何删除一个站点

我们一般的网站都是PHPMySQL开发的&#xff0c;所以删除站点&#xff0c;就要先删数据库&#xff0c;再删网站目录 注意&#xff1a;一点要确保无用的再删 删除站点目录

01 JVM -- JVM 体系结构、HotSpot

1. JVM、HotSpot、 OpenJDK 的区别 JVM (Java Virtual Machine) 是一个虚拟机HotSpot 是 JVM 规范的一个实现。HotSpot 虚拟机通过即时编译 (JIT) 技术将 Java 字节码转换为本地机器码&#xff0c;以提高程序的执行效率。OpenJDK 是一个项目名&#xff0c;它在 HotSpot 的基础…

DRF之视图集

【 一 】视图集 ​ 在 RESTful 架构中&#xff0c;对资源的常规操作无非就是查询、新增、修改、删除等这么几种。为此&#xff0c;django-rest-framework 分别提供了对应通用类视图函数。但是&#xff0c;如果对同一个资源的不同操作逻辑分散在各个视图函数中&#xff0c;从逻…

C++STL细节,底层实现,面试题04

文章目录 19. STL19.1. 序列容器19.1.1. vector19.1.1.1. 底层实现和特点19.1.1.2. 常用函数19.1.1.3. emplace_back() vs push_back() 19.1.2. array19.1.2.1. 底层实现和特点19.1.2.2. 常用函数 19.1.3. deque19.1.3.1. 底层实现和特点19.1.3.2. 常用函数 19.1.4 list19.1.4.…

性能远超GPT-4!谷歌发布Med-Gemini医疗模型;李飞飞首次创业瞄准空间智能;疫苗巨头联合OpenAl助力AI医疗...

AI for Science 企业动态速览—— * 谷歌 Med-Gemini 医疗 AI 模型性能远超 GPT-4 * 斯坦福李飞飞首次创业瞄准「空间智能」 * 疫苗巨头 Moderna 与 OpenAl 达成合作 * 美国能源部推动 AI 在清洁能源领域的应用 * 美年健康荣获「2024福布斯中国人工智能创新场景应用企业TOP10」…

2024-5-9

今日流水账&#xff1a; 上午&#xff1a;又睡懒觉了&#xff0c;9点半才起来… 还是在调之前的那个 kernel pwn&#xff0c;但是 CONFIG_SLAB_FREELIST_HARDENED 加固泄漏 cookie 哪里我还是没搞明白&#xff08;&#xff1a;服了然后去理发、冲水卡了&#xff08;&#xff1a…

Centos 7.9如何使用源码编译安装curl最新版本

文章目录 1、前言2、curl源代码下载3、openssl安装4、编译curl4.1、配置编译环境4.2、编译输出二进制curl程序4.3、安装编译后的curl4.4、编译完成检查4.5、验证安装 1、前言 Centos 7.9&#xff0c;由于系统为2017年发行&#xff0c;且以稳定性为主&#xff0c;部分工具版本较…

吴恩达机器学习笔记:第 9 周-17大规模机器学习(Large Scale Machine Learning)17.3-17.4

目录 第 9 周 17、 大规模机器学习(Large Scale Machine Learning)17.3 小批量梯度下降17.4 随机梯度下降收敛 第 9 周 17、 大规模机器学习(Large Scale Machine Learning) 17.3 小批量梯度下降 小批量梯度下降算法是介于批量梯度下降算法和随机梯度下降算法之间的算法&…

Docker Desktop 修改容器的自启动设置

Docker Desktop 允许用户控制容器的自启动行为。如果你不希望某个容器在 Docker 启动时自动启动&#xff0c;你可以通过以下步骤来更改设置&#xff1a; 1. 打开 Docker Desktop 应用。 2. 点击右上角的设置&#xff08;Settings&#xff09;按钮&#xff0c;或者使用快捷键 Cm…

2024数维杯数学建模A题B题C题思路+模型+代码(开赛后第一时间更新)

2024数维杯数学建模A题B题C题思路模型代码&#xff08;开赛后第一时间更新&#xff09; https://mbd.pub/o/bread/ZpWakpdq https://mbd.pub/o/bread/ZpWakpdq 2024年第九届数维杯大学生数学建模挑战赛参赛规则 竞赛要求及论文提交方式; ①本次参赛作品统一在线提交到竞赛…

如何进行资产梳理(信息收集)

前言 渗透测试流程 线路一:渗透测试人员 1.域名收集--(备案收集) 1.1在线收集子域名 1.1.1 站长之家 1.1.2 IP138网站 1.1.3 查子域 1.1.4 RapidDNS 1.1.5 聚名 1.1.6 Crt.sh 1.1.7 googleHack 1.2工具和资产测绘收集子域名 1.2.1 oneforall(最好用,最全面) 1.2.…

内网安全-隧道技术SSHDNSICMPSMB上线通讯LinuxMac 简单总结

第126天&#xff1a;内网安全-隧道技术&SSH&DNS&ICMP&SMB&上线通讯Linux&Mac_内网安全-隧道技术_ssh_dns_icmp_smb_上线通讯linux_mac-CSDN博客 内网渗透—隧道技术_隧道技术csdn-CSDN博客 #SMB 隧道&通讯&上线 判断&#xff1a;445 通讯 上…