剑指 Offer II 040. 矩阵中最大的矩形

ops/2025/3/6 4:20:45/

comments: true
edit_url: https://github.com/doocs/leetcode/edit/main/lcof2/%E5%89%91%E6%8C%87%20Offer%20II%20040.%20%E7%9F%A9%E9%98%B5%E4%B8%AD%E6%9C%80%E5%A4%A7%E7%9A%84%E7%9F%A9%E5%BD%A2/README.md

剑指 Offer II 040. 矩阵中最大的矩形

题目描述

给定一个由 01 组成的矩阵 matrix ,找出只包含 1 的最大矩形,并返回其面积。

注意:此题 matrix 输入格式为一维 01 字符串数组。

 

示例 1:

在这里插入图片描述

输入:matrix = ["10100","10111","11111","10010"]
输出:6
解释:最大矩形如上图所示。

示例 2:

输入:matrix = []
输出:0

示例 3:

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

示例 4:

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

示例 5:

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

 

提示:

  • rows == matrix.length
  • cols == matrix[0].length
  • 0 <= row, cols <= 200
  • matrix[i][j]'0''1'

 

注意:本题与主站 85 题相同(输入参数格式不同): https://leetcode.cn/problems/maximal-rectangle/

解法

方法一:单调栈

把每一行视为柱状图的底部,对每一行求柱状图的最大面积即可。

时间复杂度 O ( m n ) O(mn) O(mn),其中 m m m 表示 m a t r i x matrix matrix 的行数, n n n 表示 m a t r i x matrix matrix 的列数。

Python3

class Solution:def maximalRectangle(self, matrix: List[str]) -> int:if not matrix: return 0n=len(matrix[0])res=0height_row=[0]*nfor row in matrix:# 每行作为基座,累计向上的连续历史高度for j,v in enumerate(row):if v=="1":height_row[j]+=1else:height_row[j]=0 #说明无基座,不需要累计,历史高度归于0#res=max(res,self.largestRectangleArea(height_row))return resdef largestRectangleArea(self, heights: List[int]) -> int:n=len(heights)h_left_minid=[0]*nh_right_minid=[n-1]*nst=[]for i,h in enumerate(heights):while st and heights[st[-1]]>h:idx=st.pop()h_right_minid[idx]=i-1st.append(i)heights_copy=heights[::-1]st = []for i, h in enumerate(heights_copy):while st and heights_copy[st[-1]] > h:idx = st.pop()h_left_minid[n-1-idx] = n-1-i + 1st.append(i)return max((r-l+1)*h for h,r,l in zip(heights,h_right_minid,h_left_minid))
Java
class Solution {public int maximalRectangle(String[] matrix) {if (matrix == null || matrix.length == 0) {return 0;}int n = matrix[0].length();int[] heights = new int[n];int ans = 0;for (var row : matrix) {for (int j = 0; j < n; ++j) {if (row.charAt(j) == '1') {heights[j] += 1;} else {heights[j] = 0;}}ans = Math.max(ans, largestRectangleArea(heights));}return ans;}private int largestRectangleArea(int[] heights) {int res = 0, n = heights.length;Deque<Integer> stk = new ArrayDeque<>();int[] left = new int[n];int[] right = new int[n];Arrays.fill(right, n);for (int i = 0; i < n; ++i) {while (!stk.isEmpty() && heights[stk.peek()] >= heights[i]) {right[stk.pop()] = i;}left[i] = stk.isEmpty() ? -1 : stk.peek();stk.push(i);}for (int i = 0; i < n; ++i) {res = Math.max(res, heights[i] * (right[i] - left[i] - 1));}return res;}
}
C++
class Solution {
public:int h[210];int l[210], r[210];int maximalRectangle(vector<string>& matrix) {int n = matrix.size();if (n == 0) return 0;int m = matrix[0].size();int ans = 0;stack<int> st;for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {h[j] = (matrix[i][j] == '1' ? h[j] + 1 : 0);while (st.size() && h[j] <= h[st.top()]) {ans = max(ans, (j - l[st.top()] - 1) * h[st.top()]);st.pop();}if (st.size())l[j] = st.top();elsel[j] = -1;st.push(j);}while (st.size()) {ans = max(ans, (m - 1 - l[st.top()]) * h[st.top()]);st.pop();}}return ans;}
};
Go
func maximalRectangle(matrix []string) int {if len(matrix) == 0 {return 0}n := len(matrix[0])heights := make([]int, n)ans := 0for _, row := range matrix {for j, v := range row {if v == '1' {heights[j]++} else {heights[j] = 0}}ans = max(ans, largestRectangleArea(heights))}return ans
}func largestRectangleArea(heights []int) int {res, n := 0, len(heights)var stk []intleft, right := make([]int, n), make([]int, n)for i := range right {right[i] = n}for i, h := range heights {for len(stk) > 0 && heights[stk[len(stk)-1]] >= h {right[stk[len(stk)-1]] = istk = stk[:len(stk)-1]}if len(stk) > 0 {left[i] = stk[len(stk)-1]} else {left[i] = -1}stk = append(stk, i)}for i, h := range heights {res = max(res, h*(right[i]-left[i]-1))}return res
}
Swift
class Solution {func maximalRectangle(_ matrix: [String]) -> Int {guard let firstRow = matrix.first else {return 0}let n = firstRow.countvar heights = [Int](repeating: 0, count: n)var ans = 0for row in matrix {for (j, char) in row.enumerated() {if char == "1" {heights[j] += 1} else {heights[j] = 0}}ans = max(ans, largestRectangleArea(heights))}return ans}private func largestRectangleArea(_ heights: [Int]) -> Int {var res = 0let n = heights.countvar stack = [Int]()var left = [Int](repeating: -1, count: n)var right = [Int](repeating: n, count: n)for i in 0..<n {while !stack.isEmpty && heights[stack.last!] >= heights[i] {right[stack.removeLast()] = i}left[i] = stack.isEmpty ? -1 : stack.last!stack.append(i)}for i in 0..<n {res = max(res, heights[i] * (right[i] - left[i] - 1))}return res}
}

方法二

C++
class Solution {
public:int maximalRectangle(vector<string>& matrix) {if (matrix.empty()) return 0;int n = matrix[0].size();vector<int> heights(n);int ans = 0;for (auto& row : matrix) {for (int j = 0; j < n; ++j) {if (row[j] == '1')++heights[j];elseheights[j] = 0;}ans = max(ans, largestRectangleArea(heights));}return ans;}int largestRectangleArea(vector<int>& heights) {int res = 0, n = heights.size();stack<int> stk;vector<int> left(n, -1);vector<int> right(n, n);for (int i = 0; i < n; ++i) {while (!stk.empty() && heights[stk.top()] >= heights[i]) {right[stk.top()] = i;stk.pop();}if (!stk.empty()) left[i] = stk.top();stk.push(i);}for (int i = 0; i < n; ++i)res = max(res, heights[i] * (right[i] - left[i] - 1));return res;}
};

http://www.ppmy.cn/ops/163496.html

相关文章

WeakAuras Lua Script TOC

十字军的试炼&#xff0c;刺骨之寒&#xff0c;插件&#xff0c;团队高亮提示 WA-Script字符串&#xff1a; !WA:2!TRZAZTX11PLWVeKJJinRQTIscmTScPenkbPeRTNWKcqckbl(YaGKY6XaSl2lWUwG7UE3f8HsDQnRQTCDSDmRJTgBpojCC80jXX2f2v2wtI)G6FGZWPJh2V0pOXK2AM(KTnoTnzCp37DxGfGlOivt…

计算机网络——IP地址

一、IP地址是什么&#xff1f; 定义 IP地址是互联网协议&#xff08;Internet Protocol&#xff09;为每台联网设备分配的唯一标识符&#xff0c;由一串数字&#xff08;IPv4&#xff09;或字母与数字组合&#xff08;IPv6&#xff09;构成。 核心作用&#xff1a;定位设备位置…

【分享】网间数据摆渡系统,如何打破传输瓶颈,实现安全流转?

在数字化浪潮中&#xff0c;企业对数据安全愈发重视&#xff0c;网络隔离成为保护核心数据的重要手段。内外网隔离、办公网与研发网隔离等措施&#xff0c;虽为数据筑牢了防线&#xff0c;却也给数据传输带来了诸多难题。传统的数据传输方式在安全性、效率、管理等方面暴露出明…

RabbitMQ快速入门

目录 MQ简介 1、同步通信 图片 2、异步通信 图片 RabbitMQ快速上手 基本介绍&#xff1a; Producer和Consumer Connection和Channel Virtual host Queue Exchange 工作流程 AMQP Java编写RabbitMQ生产者消费者 生产者 1.建立连接 2.开启信道 3.声明交换机 4.声…

QT实现计算器

1&#xff1a;在注册登录的练习里面&#xff0c; 追加一个QListWidget 项目列表 要求&#xff1a;点击注册之后&#xff0c;将账号显示到 listWidget上面去 以及&#xff0c;在listWidget中双击某个账号的时候&#xff0c;将该账号删除 Widget.h #ifndef WIDGET_H #define…

leetcode 56. 合并区间

题目如下 数据范围 对区间排序从左到右遍历&#xff0c;维持l作为当前区间的最左边边界就行&#xff0c;维持r作为右端点随后判断区间是否重叠。通过代码 class Solution { public:static bool cmp(const vector<int> &a,const vector<int> &b){if(a[…

单元测试与仿真程序之间的选择

为什么写这篇文章 现在的工作需求&#xff0c;让我有必要总结和整理一下。 凡事都有适用的场景。首先这里我需要提示一下&#xff0c;这里的信息&#xff0c;可能并不普适。 但是可以肯定一点的是&#xff0c;有些人&#xff0c;不论做事还是写书&#xff0c;上下文还没有交待…

【C#】检查已有窗口,防止重复打开

winform项目只允许打开一个窗口 在 WinForms 项目中&#xff0c;如果 希望 程序只允许打开一个主窗口&#xff0c;可以使用 单实例模式&#xff0c;防止用户重复启动应用程序。 ✅ 方法 1&#xff1a;检查已有窗口&#xff0c;防止重复打开&#xff08;推荐&#xff09; 如果 …