算法37:最大矩形(力扣84、85题)---单调栈

力扣84题:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

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

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

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

分析:

1. 其实,这一题就是找数组的最大相同部分,也就是说尽可能的找到各个柱子凑在一起,找出最大的共有部分。

2. 当然,如果其中一个柱子很高,而其他柱子很矮,那也有可能最大面积就取那个很高的柱子

3. 很显然,这一题跟柱子的高度以及所有柱子的共有部分有关。典型的单调栈结构

4. 既然是单调栈,那就假设没根柱子的高度是最大值,然后找左侧、右侧离当前柱子的最近距离。中间就是共有性质。

package code04.单调栈_01;import java.util.Stack;/*** 力扣84题,柱状图中最大的矩形* https://leetcode.cn/problems/largest-rectangle-in-histogram/description/*/
public class Code02_HistogramMaxRectangleCount {public int largestRectangleArea(int[] heights){if (heights == null || heights.length == 0) {return 0;}int max = 0;Stack<Integer> stack = new Stack<>();for (int i = 0; i < heights.length; i++) {//以栈顶元素为高。如果出现比栈顶元素小的值,结束当前高度的左右扩展while (!stack.isEmpty() && heights[stack.peek()] > heights[i]){int curIndex = stack.pop();//如果有下标就减掉,没有下标说明从头开始,需要额外加1个。这里的-1用的很巧妙int leftIndex = stack.isEmpty() ? -1 : stack.peek();//i位置出现了小于当前说的情况,i位置的数不包含,因此需要往左移动一个max = Math.max(max, heights[curIndex] * (i - 1 - leftIndex));}stack.push(i);}while (!stack.isEmpty()) {int curIndex = stack.pop();//如果有下标就减掉,没有下标说明从头开始,需要额外加1个。这里的-1用的很巧妙int leftIndex = stack.isEmpty() ? -1 : stack.peek();//heights.length - 1代表最后一个数的下标,是包含的。max = Math.max(max, heights[curIndex] * (heights.length - 1 - leftIndex));}return max;}public static void main(String[] args) {Code02_HistogramMaxRectangleCount ss = new Code02_HistogramMaxRectangleCount();int[] heights = {2,1,5,6,2,3};System.out.println(ss.largestRectangleArea(heights));}
}

力扣85题:https://leetcode.cn/problems/maximal-rectangle

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

10100
10111
11111
10010

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

上一题,我们是一维数组中求柱子的最大面积,而这一题却时二维数组。有没有办法也转换成一维数组呢?答案是有的。

思路:

1. 第一行最大面积为1, 因为所有的1都是断开的

2. 第一个和第二行数组压缩。得到2、0、2、1、1。 通过单调栈可以知道最大面积为3.

3. 前三行数组压缩,得到 3、1、3、2、2. 通过单调栈可得最大面积为6.

4. 所有行数组压缩,得到 4、0、0、3、0。 因为0代表是断开的,既然是断开的,那么之前行已经使用过了这些数据并且得到了

package code04.单调栈_01;import java.util.Stack;/*** 力扣85题,最大矩形* https://leetcode.cn/problems/maximal-rectangle/*/
public class Code03_MaxRectangleCount {public int maximalRectangle(char[][] matrix){if (matrix == null || matrix.length == 0) {return 0;}int[] dp = new int[matrix[0].length];int ans = 0;for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < matrix[i].length; j++) {int cur = matrix[i][j] == '0' ? 0 : Integer.parseInt(String.valueOf(matrix[i][j]));dp[j] = dp[j] + cur;}ans = Math.max(ans, largestRectangleArea(dp));}return ans;}public int largestRectangleArea(int[] heights){int max = 0;Stack<Integer> stack = new Stack();for (int i = 0; i < heights.length; i++) {while (!stack.isEmpty() && heights[stack.peek()] >= heights[i]) {//当前列int cur = stack.pop();//当前列前一个比自己小的值的下标int left = stack.isEmpty() ? -1 : stack.peek();//范围内,当前列的高度为共性,求出最大公共部分值max = Math.max(max, heights[cur] * (i - 1 - left));}stack.push(i);}while (!stack.isEmpty()) {int cur = stack.pop();int left = stack.isEmpty() ? -1 : stack.peek();max = Math.max(max, heights[cur] * (heights.length - 1 - left));}return max;}public static void main(String[] args) {Code03_MaxRectangleCount ss = new Code03_MaxRectangleCount();char[][] matrix = {{'1','0','1','0','0'},{'1','0','1','1','1'},{'1','1','1','1','1'},{'1','0','0','1','0'}};System.out.println(ss.maximalRectangle(matrix));}
}

最大值。那么当前行就没有必要再次使用了。因此当前行某一列为0,那么数组压缩直接为0.   目测,我们就知道最大值为4.

5. 通过数组压缩以后,我们知道这个二维数组的最大值就为6.

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

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

相关文章

[每日一题] 01.26 - 最长连号

最长连号 n int(input()) lis list(map(int,input().split())) res for i in range(n - 1):if lis[i] 1 lis[i 1]:res 1else:res 0res res.split(0) print(len(max(res)) 1)或者&#xff1a; n int(input()) lis list(map(int,input().split()))Max 1 for i in …

研发日记,Matlab/Simulink避坑指南(五)——CAN解包 DLC Bug

文章目录 前言 背景介绍 问题描述 分析排查 解决方案 总结 前言 见《研发日记&#xff0c;Matlab/Simulink避坑指南&#xff08;一&#xff09;——Data Store Memory模块执行时序Bug》 见《研发日记&#xff0c;Matlab/Simulink避坑指南(二)——非对称数据溢出Bug》 见《…

win10安装redis并配置加自启动(采用官方推荐unix子系统)

记录&#xff0c;为啥有msi安装包&#xff0c;还这么麻烦的用linux版本redis的安装方式&#xff0c;是因为从github上下载别人制作的msi报毒&#xff0c;还不止一处&#xff0c;这种链接数据库的东西&#xff0c;用别人加工过的&#xff0c;都报毒了还用就是傻逼了。 所以采用…

spring(三):IOC介绍及代码实现

1. IoC容器概述 IoC 是 Inversion of Control 的简写&#xff0c;译为“控制反转”&#xff0c;它不是一门技术&#xff0c;而是一种设计思想&#xff0c;是一个重要的面向对象编程法则&#xff0c;能够指导我们如何设计出松耦合、更优良的程序。 Spring 通过 IoC 容器来管理…

【第四天】蓝桥杯备战

题 1、求和2、天数3、最大缝隙 1、求和 https://www.lanqiao.cn/problems/1442/learning/ 解法&#xff1a;字符串方法的应用 import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改public class Main {public static void main(String[] args) {Scann…

Linux命令-apk命令(Alpine Linux 下的包管理工具)

使用实例 apk install xxx apk search xxx # 支持正则 apk info xxx # 查看包的详细信息 apk show # list local package # 卸载并删除 包 apk del openssh openntp vim升级 upgrade命令升级系统已安装的所以软件包&#xff08;一般包括内核&#xff09;&#xff0c;当然也可…

c++ vector 赋值 只能用push_back()赋值 ?使用下标赋值出错,不能使用标赋值吗?

文章目录 1 push_back()赋值2 下标赋值2.1 下标赋值出错2.2 vector 真的 不能使用标赋值吗&#xff1f;2.2.1 只能使用push_back() 赋值情况2.2.2 push_back() 和 下标赋值 都可以2.2.3 先push_back()赋值&#xff0c;再下标赋值 2.3 push_back() 和 下标赋值 两种特点对比测试…

谷粒商城【成神路】-【1】——项目搭建

目录 &#x1f95e;1.整体架构图 &#x1f355;2.微服务划分图 &#x1f354;3.开发环境 &#x1f354;4.搭建git &#x1f32d;5.快速搭建服务 &#x1f37f;6.数据库搭建 &#x1f9c2;7.获取脚手架 &#x1f953;8.代码生成器 &#x1f373;9.创建公共模块 …

论文笔记(四十二)Diff-DOPE: Differentiable Deep Object Pose Estimation

Diff-DOPE: Differentiable Deep Object Pose Estimation 文章概括摘要I. 介绍II. 相关工作III. DIFF-DOPEIV. 实验结果A. 实施细节和性能B. 准确性C. 机器人-摄像机校准 V. 结论VI. 致谢 文章概括 作者&#xff1a;Jonathan Tremblay, Bowen Wen, Valts Blukis, Balakumar Su…

命令提示符

echo $PS1命令显示当前命令提示符的格式。 [rootlocalhost ~]# echo $PS1 [\u\h \W]\$参数含义 \u 代表是用户 user 分割符号\h 代表主机名 hostname\W 代表当前的工作目录&#xff08;当前的路径&#xff09; working\$ 如果你是root用户就是# &#xff0c;如果你是非root用户…

品牌突围|内容营销「共创公式」全面讲解

为什么品牌要扎根小红书&#xff1f;除了种草投放&#xff0c;品牌还能做些什么&#xff1f; 在小红书&#xff0c;迎接消费者共创的时代&#xff0c;激活品牌营销的无限潜能。 拥抱多元 在新机遇中预见未来 2023年&#xff0c;各大社交媒体平台涌现出了许多热点&#xff0c…

项目中日历管理学习使用

一些项目中会有日历或日期设置&#xff0c;最基本的会显示工作日&#xff0c;休息日&#xff0c;节假日等等&#xff0c;下面就是基于项目中的日历管理功能&#xff0c;要显示工作日&#xff0c;休息日&#xff0c;节假日 效果图 获取国家法定节假日工具类 public class Holi…

vue3中下载预览文件方法封装(已获取文件地址)

1.封装方法 在src/utils文件夹下新建文件previewDownFile.js import axios from "axios"; import { ElMessage} from "element-plus";export function previewBtn(url,fileName) { // url-下载预览地址 fileName-文件名if (!fileName) { // 图片预览wind…

P1591 阶乘数码题解

题目 求n!中某个数码出现的次数。 输入输出格式 输入格式 第一行为t(t≤10)&#xff0c;表示数据组数。接下来t行&#xff0c;每行一个正整数n(n≤1000) 和数码a。 输出格式 对于每组数据&#xff0c;输出一个整数&#xff0c;表示n!中a出现的次数。 输入输出样例 输入…

SpringMVC-域对象共享数据

文章目录 域对象共享数据一、三种域对象二、通过ServletAPI向Request域对象共享数据三、使用ModelAndView向Request域对象共享数据四、使用Model向Request域对象共享数据五、使用Map向Request域对象共享数据六、使用ModelMap向Request域对象共享数据七、向Session域对象共享数据…

go-zero配置DB的redis缓存

配置定义&#xff1a; # cat internal/config/config.go package configimport ("github.com/zeromicro/go-zero/rest""github.com/zeromicro/go-zero/core/stores/cache" )type Config struct {rest.RestConfCacheRedis cache.CacheConf }对应的配置文件…

项目中遇到通过域名访问服务提示 Service name unknow

目录 项目中遇到通过域名访问服务提示 Service name unknow 1.问题描述2.问题原因3.解决思路4.解决方案文章所属专区 项目问题解决 1.问题描述 在CentOS 系统环境下 项目中遇到通过域名访问服务提示 Service name unknow,但是 网络是连通的 通过ping 和telnet都能够验证。 …

再学webpack

1 优化 webpack 打包体积的思路 优化 webpack 打包体积的思路包括&#xff1a; 提取第三方库或通过引用外部文件的方式引入第三方库&#xff1a;将第三方库单独打包&#xff0c;并通过 CDN 引入&#xff0c;减少打包体积。使用代码压缩插件&#xff1a;例如 UglifyJsPlugin&a…

GBASE南大通用分享-linux centos下安装dokuwiki

GBASE南大通用分享 首先先大致介绍一下wiki&#xff1a; DokuWiki是一个开源wiki引擎程序&#xff0c;运行于PHP环境下。Doku Wiki 程序小巧而功能强大、灵活&#xff0c;适合中小团队和个人网站知识库的管理。 DokuWiki可以与多种CMS程序进行整合&#xff0c;例如WordPress…

【江科大】STM32:外部中断(Extern Interrupt)

文章目录 EXTI&#xff08;Extern Interrupt&#xff09;外部中断EXIT的基本结构EXIT框图 旋转编码器简介库函数&#xff1a;对射式红外传感器计次&#xff1a;代码展示&#xff1a;旋转编码器计次注意&#xff1a; EXTI&#xff08;Extern Interrupt&#xff09;外部中断 功能…