Leetcode 85.最大矩形(困难)

news2024/11/25 2:48:45

一、题目

1、题目描述

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

示例1:

输入: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

示例3:

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

示例4:

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

示例5:

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

2、基础框架

class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        
    }
};

3、原题链接

Leetcode 85. 最大矩形

二、解题报告

1、思路分析

(1)暴力解法
n ∗ n n*n nn 的矩阵中的子矩阵个数为 n 4 n ^4 n4,因为在 n ∗ n n * n nn 的矩阵中,随便选择一个点作为点 A 的选法有 n 2 n ^2 n2 种,随便选择一个点作为点 B 的选法有 n 2 n ^2 n2 种,而 A 和 B 一个作为左上角,一个作为右下角,可以得到一个矩形,可能有重复的,但是没有关系,所以得到子矩阵的个数为 n 2 ∗ n 2 = n 4 n ^ 2 * n^2 = n ^4 n2n2=n4

暴力解就是 4 重 for 循环枚举出每个子矩阵,然后再 2 重 for 循环验证该子矩阵中是不是每个位置都是 1,所以总的时间复杂度是 O ( n 6 ) O(n ^6) O(n6)

(2)非暴力解法
例子:
在这里插入图片描述
先求子矩阵必须以第 0 行作为地基的情况下,哪个子矩阵包含的 1 最多,即将其作为直方图考虑
请添加图片描述
然后求必须以第 1 行作为地基,第 1 行的高度压到第 0 行上,遇到 0 的情况,将高度处理为0。这是数组压缩 技巧:
请添加图片描述
然后求必须以第 2 行作为地基,第 2 行压到之前的高度上,同样地,遇到 0 时,将高度处理为 0,将得到如下的结果:
请添加图片描述
最后必须以第 3 行作为地基,第 3 行压到之前的高度上:
请添加图片描述
这就得到了必须以第 3 行作为地基的情况下的子数组。

客观上,最大矩形肯定是以某一行作为地基的,上面的流程就列举了所有的可能性。

每一行处理都需要用到单调栈:压缩后的数组以每个位置为矩形的高度可能扩充的范围

每一行处理的时间复杂度为 O ( n ) O(n) O(n),一共 n n n 行需要处理,所以总的时间复杂度就是 O ( n 2 ) O(n^2) O(n2)

2、时间复杂度

O ( n 2 ) O(n^2) O(n2)

3、代码详解

C++ 版

  • 不使用系统stack版
class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        if (matrix.size() == 0 || matrix[0].size() == 0) 
            return 0;

        //压缩数组得到直方图数组
        int row = matrix.size();
        int col = matrix[0].size();
        int heights[col];
        memset(heights, 0, sizeof(heights));

        int ans = 0;

        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                heights[j] = matrix[i][j] == '0' ? 0 : heights[j] + 1;
            }
            ans = max(ans, maxRectangle(heights, col));
        }

        return ans;
    }
	
	//对每一行处理得到的直方图都用单调栈求解最大矩形
    int maxRectangle(int *heights, int col) {
        int _stack[col];
        memset(_stack, 0, sizeof(_stack));

        int si = -1;

        int ans = 0;
        for (int i = 0; i < col; i++) {
            while (si != -1 && heights[_stack[si]] >= heights[i]) {
                int cur = heights[_stack[si--]];
                int left = si == -1 ? -1 : _stack[si];
                int area = cur * (i - left - 1);
                ans = max(ans, area);
            }
            _stack[++si] = i;
        }

        while (si != -1) {
            int cur = heights[_stack[si--]];
            int left = si == -1 ? -1 : _stack[si];
            int area = cur * (col - left - 1);
            ans = max(ans, area);
        }

        return ans;
    }
};
  • 使用系统stack版
class Solution {
public:
    int maximalRectangle(vector<vector<char>>& matrix) {
        
        if (matrix.size() == 0 || matrix[0].size() == 0) return 0;

        int row = matrix.size();
        int col = matrix[0].size();

        int ans = 0;
        //准备一个直方图数组
        int heights[col];
        memset(heights, 0, sizeof(heights));

        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                heights[j] = matrix[i][j] == '0' ? 0 : heights[j] + 1;
            }
            ans = max(ans, maxRecFromBottom(heights, col));
        }

        return ans;
    }

    int maxRecFromBottom(int *heights, int len) {
        if (len == 0) return 0;

        int area = 0;
        stack<int> sta;
        for (int i = 0; i < len; i++) {
            while (!sta.empty() && heights[sta.top()] >= heights[i]) {
                int j = sta.top();
                sta.pop();
                int k = sta.empty() ? -1 : sta.top();
                area = max(area, (i - k - 1) * heights[j]);
            }
            sta.push(i);
        }


        while (!sta.empty()) {
            int j = sta.top();
            sta.pop();
            int k = sta.empty() ? -1 : sta.top();
            int curArea = (len - k - 1) * heights[j];
            area = max(area, curArea);
        }

        return area;
    }

};

Java 版

public class Code04_MaximalRectangle {

	public static int maximalRectangle(char[][] map) {
		if (map == null || map.length == 0 || map[0].length == 0) {
			return 0;
		}
		int maxArea = 0;
		int[] height = new int[map[0].length]; //准备一个直方图数组
        //处理得到直方图数组
		for (int i = 0; i < map.length; i++) {
			for (int j = 0; j < map[0].length; j++) {
				height[j] = map[i][j] == '0' ? 0 : height[j] + 1;
			}
			maxArea = Math.max(maxRecFromBottom(height), maxArea); //对每一行处理得到的直方图都用单调栈求解
		}
		return maxArea;
	}

	// height是直方图数组
	public static int maxRecFromBottom(int[] height) {
		if (height == null || height.length == 0) {
			return 0;
		}
		int maxArea = 0;
		Stack<Integer> stack = new Stack<Integer>();
		for (int i = 0; i < height.length; i++) {
			while (!stack.isEmpty() && height[i] <= height[stack.peek()]) {
				int j = stack.pop();
				int k = stack.isEmpty() ? -1 : stack.peek();
				int curArea = (i - k - 1) * height[j];
				maxArea = Math.max(maxArea, curArea);
			}
			stack.push(i);
		}
		while (!stack.isEmpty()) {
			int j = stack.pop();
			int k = stack.isEmpty() ? -1 : stack.peek();
			int curArea = (height.length - k - 1) * height[j];
			maxArea = Math.max(maxArea, curArea);
		}
		return maxArea;
	}
}

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

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

相关文章

基于微信小程序奶茶店在线点单管理系统ssm框架-计算机毕业设计

面对目前奶茶店林立的现状&#xff0c;大城市奶茶店多为连锁奶茶店他们都有统一的管理和相应的系统。但是个别小县城和小城以及城区也有不少的奶茶店多为自营&#xff0c;这就必须店长自己管理和采购原料。大型连锁的奶茶店管理系统就不适用于分散的小型奶茶店。小型奶茶店的管…

剑指 Offer 10- II. 青蛙跳台阶问题

一、题目描述 一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级台阶。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 答案需要取模 1e97&#xff08;1000000007&#xff09;&#xff0c;如计算初始结果为&#xff1a;1000000008&#xff0c;请返回 1。 二、示例 示…

TaWRKY19/61/82激活糖转运蛋白TaSTP3从而增强小麦条锈病敏感性

文章信息 题目&#xff1a;Sugar transporter TaSTP3 activation by TaWRKY19/61/82 enhances stripe rust susceptibility in wheat 刊名&#xff1a;New Phytologist 作者&#xff1a;Baoyu Huai&#xff0c;Zhensheng Kang,Jie Liu et al. 单位&#xff1a;Northwest A&…

【C++】string使用模拟实现

文章目录前言为什么学习string类&#xff1f;1. string函数常用接口介绍1.1 string容器基本概念1.2 string构造函数1.3 string访问和修改1.4 string插入和删除1.5 string赋值操作1.5 string字符串拼接1.7 string查找和替换1.8 string子串1.9 string类对象的容量操作2. string类…

dockerfile编写

dockerfile编写 dcoker 的一个操作和交互的关系流程: dockerfile 编写规则 习惯使用大写非注释行第一行必须是FROM文件名必须是dockerfile指定一个专门的工作目录所有引入的映射文件必须在这个工作空间目录下工作空间不支持隐藏文件(.dockeringore)作用是用于存放不需要打包…

2022最新iOS最新打包发布流程

关于如何发布iOS应用到App Stroe&#xff0c;苹果开发者中心已经给出了很详细的说明。和普通的iOS应用一样&#xff0c;使用React Native开发的iOS应用也需要使用普通的iOS应用的发布流程&#xff0c;总的来说&#xff0c;主要涉及以下几步&#xff1a; 加入苹果开发者计划&am…

【Android进阶之旅】内存泄漏的危害有哪些?(案例分析)

随着计算机应用需求的日益增加&#xff0c;应用程序的设计与开发也相应的日趋复杂&#xff1b; 开发人员在程序实现的过程中处理的变量也大量增加&#xff0c;如何有效进行内存分配和释放&#xff0c;防止内存泄漏的问题变得越来越突出 例如&#xff1a; 服务器应用软件&#x…

connection is being used##server is in use and cannot be deleted

mysql数据库被黑客挟持&#xff0c;删除我的数据库&#xff0c;让我用比特币来换&#xff0c;吓死我了&#xff0c;还好是测试库&#xff0c;删了就删了&#xff0c;数据库备份还得做好&#xff0c;密码不能设置太简单了。 下面是黑客留言&#xff1a; "以下数据库已被删…

64-65 - C++中的异常处理

---- 整理自狄泰软件唐佐林老师课程 1. C异常处理 1.1 try catch内容一 C内置了异常处理的语法元素 try catchtry语句用于处理正常代码逻辑catch语句用于处理异常情况 try语句中的异常由对应的catch语句处理 1.2 C通过throw语句抛出异常信息 1.3 C异常处理分析 throw抛出的…

【SSM注解汇总】

SSM注解汇总 文章目录SSM注解汇总MyBatis注解1. param("param1","param2",...)2. MapKey("id")Spring注解1. IOC Component Service Controller Repository2. 基于注解方式实现属性注入1&#xff09;Autowired2&#xff09;Qualifier3&#xff0…

Allegro铜皮动静态切换操作指导

Allegro铜皮动静态切换操作指导 Allegro支持铜皮的动静态相互切换,并且还可以批量操作,具体操作如下 动态切换成静态 以下面图片为例,这是个动态铜皮dynamic属性 点击选择铜皮命令 选中铜皮 右击选择change shape type 会出现一个弹窗警告,直接点击是 铜皮被change成…

海外仓物流有哪些优缺点

海外仓的优点&#xff1a;较低的物流成本、更有效率的送货时效、优质的仓储管理经验、订单处理省时省力、库存管理及盘点清晰明确、远程操作省时省力、自动快捷的退换货处理流程等。海外仓的缺点&#xff1a;存储压力大&#xff0c;库存成本高&#xff0c;资金运转不便等。海外…

微软威胁建模工具 STRIDE

威胁建模要回答的四个问题 what are we woking on what can go wrong what are we going to do about this did we do a good enough job 说到threat modeling 不得不提的就是微软的STRIDE 微软也提供了工具来做这个工作 Microsoft Threat Modeling Tool overview - Azur…

tictoc例子理解10-13

tictoc10-13tictoc 10 几个模块连接&#xff0c;发送消息直到模块3收到消息tictoc 11 新增信道定义tictoc 12 双向连接信息简化定义tictoc 10 几个模块连接&#xff0c;发送消息直到模块3收到消息 让我们用几个(n)’ tic’模块让它更有趣&#xff0c;并将每个模块连接到其他模…

基于Android的学生管理系统App设计与实现(Eclipse开发)

目 录 摘 要 I Abstract II 1 绪论 1 1.1 选题背景及意义 1 1.2 研究现状 1 1.2.1 教育系统发展现状 1 1.2.2 手机的应用市场发展现状 1 1.2.3 Android平台介绍 3 1.2.4 Android管理学生信息的意义 5 1.3.3 开发的环境及开发工具介绍 6 1.3 研究主要内容 6 2 相关技术介绍 7 2.…

安装 laravel 遇到的错误和解决方案

安装 laravel 遇到的错误和解决方案 纯粹是为了运行下 laravel&#xff0c;遇到了错误记录下&#xff0c;分享给需要的人。 下载 PHP Windows 版 &#xff0c;我选择的版本是 PHP 7.4 (7.4.33)。下载文件以后找个文件夹解压就可以了。Composer 安装&#xff0c;官网 。 勾选以…

单元测试与数据库

单元测试 1.单元测试应该是全自动执行的,而非交互式的,应使用assert语句来验证结果而不是sout后进行人眼验证 2.为了保证单元测试可靠且便于维护,单元测试用例之间不能互相调用 3.单元测试是可重复执行的,不能受到外界环境的影响 4.单元测试代买必须写在src/test/java的工程…

【JAVA程序设计】基于SpringBoot+VUE的高校疫情打卡系统-前后端分离

基于SpringBootVUE的高校疫情打卡系统零、项目获取一、项目简介二、开发环境三、项目技术四、系统架构五、运行截图六、数据库设计零、项目获取 获取方式&#xff08;点击下载&#xff09;&#xff1a;是云猿实战 项目经过多人测试运行&#xff0c;可以确保100%成功运行。 一…

【C++11重点语法】lambda表达式,初始化列表

目录 引子&#xff1a;C11为什么的源来 语法1&#xff1a;初始化列表 1.2.2 多个对象的列表初始化 语法3&#xff1a;默认成员函数控制&#xff08;delete&#xff0c;default&#xff09; 语法4&#xff1a;lambda表达式 引子&#xff1a;C11为什么的源来 在2003年C标准…

[附源码]计算机毕业设计springboot课室预约系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…