leetcode 221. Maximal Square & 85. Maximal Rectangle

221. Maximal Square

Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area.

For example, given the following matrix:

1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Return 4.

注意这里的区域是方阵。
对于位置(i,j) 如果其左边,上面,跟左上角都为1,才能算是一个局部的方阵成功。所以dp[i][j] = min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1])+1。
如果(i,j)为0, dp[i][j]直接为0
这里dp[i][j]记录的其实是方阵的边长。

public class Solution {
    public int maximalSquare(char[][] matrix) {
        if(matrix==null||matrix.length==0) return 0;
        int w = matrix.length;
        int h = matrix[0].length;
        int[][] dp = new int[w+1][h+1];

        int res = 0;
        for(int i=1; i<w+1; i++){
            for(int j=1; j<h+1;j++){
                if(matrix[i-1][j-1] == '1'){
                    dp[i][j] = Math.min(dp[i-1][j-1], Math.min(dp[i-1][j], dp[i][j-1])) + 1;
                    res = Math.max(dp[i][j], res);
                }
            }
        }
        return res*res;
    }
}

对于不需要是方阵,是矩形即可的情况

85. Maximal Rectangle

Given a 2D binary matrix filled with 0's and 1's, find the largest rectangle containing only 1's and return its area.

For example, given the following matrix:

1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0
Return 6.

对于点(i,j),如果为1,记录其左边第一个1,包括自身的位置,记为left[i][j],记录其右边第一个零的位置,记为right[i][j]。这里指的注意的是,left和right还需要根据上一层的left和right来判断。left[i][j] = max(left[i-1][j],left[i][j]),保证矩阵的向上扩展。同理right应该取min。
如果其上边的点不为零,那么矩阵的高度加1,height[j]++,这样包括点(i,j)的矩阵的最大矩阵为height[j] *(right[i][j] - left[i][j])。

public class Solution {
    public int maximalRectangle(char[][] matrix) {
        if(matrix==null || matrix.length==0) return 0;
        int w = matrix.length;
        int h = matrix[0].length;
        int[] left = new int[h], right = new int[h], height = new int[h];
        Arrays.fill(right, h);
        int res =0;

        for(int i=0; i<w; i++){
            int cur_l = 0, cur_r = h;
            for(int j=0; j<h;j++){
                if(matrix[i][j]=='1'){
                    height[j]++;
                    left[j] = Math.max(left[j], cur_l);
                }else{
                    cur_l = j+1;
                    height[j] = 0;
                    left[j] = 0;
                }
            }

            for(int j = h-1; j>=0; j--){
                if(matrix[i][j]=='1'){
                    right[j] = Math.min(right[j], cur_r);
                }else{
                    right[j] = h;
                    cur_r = j;
                }
            }
            for(int j = 0; j < h; j++){
                res = Math.max(res, (right[j] - left[j])*height[j]);
            }
        }  

        return res;

    }
}
LeetCode85 题的题目名称是: ## **Maximal Rectangle**(最大矩形) --- ### 🔹题目描述: 给定一个只包含 `0` 和 `1` 的二维二进制矩阵 `matrix`,找出只包含 `1` 的最大矩形,并返回其面积。 --- ### 🔹示例: ```text 输入: [ [&quot;1&quot;,&quot;0&quot;,&quot;1&quot;,&quot;0&quot;,&quot;0&quot;], [&quot;1&quot;,&quot;0&quot;,&quot;1&quot;,&quot;1&quot;,&quot;1&quot;], [&quot;1&quot;,&quot;1&quot;,&quot;1&quot;,&quot;1&quot;,&quot;1&quot;], [&quot;1&quot;,&quot;0&quot;,&quot;0&quot;,&quot;1&quot;,&quot;0&quot;] ] 输出: 6 ``` 解释: 最大矩形是由第二行和第三行中的 `1` 构成的,大小为 `2 x 3 = 6`。 --- ### 🔹解法思路: 这道题是 **LeetCode 84(Largest Rectangle in Histogram)** 的二维扩展。 我们可以将每一行看作是直方图的底部,并逐行构建&ldquo;高度数组&rdquo;,然后对每一行使用 LeetCode 84 的单调栈解法来计算当前行所能构成的最大矩形面积。 --- ### 🔹C++ 实现代码: ```cpp #include &lt;iostream&gt; #include &lt;vector&gt; #include &lt;stack&gt; using namespace std; // LeetCode 84 的函数:直方图中最大矩形面积 int largestRectangleArea(vector&lt;int&gt;&amp; heights) { stack&lt;int&gt; s; int maxArea = 0; heights.push_back(0); // 添加一个0,确保最后所有元素都被弹出 for (int i = 0; i &lt; heights.size(); ++i) { while (!s.empty() &amp;&amp; heights[i] &lt; heights[s.top()]) { int height = heights[s.top()]; s.pop(); int width = s.empty() ? i : i - s.top() - 1; maxArea = max(maxArea, height * width); } s.push(i); } heights.pop_back(); // 恢复原数组 return maxArea; } // LeetCode 85 主函数 int maximalRectangle(vector&lt;vector&lt;char&gt;&gt;&amp; matrix) { if (matrix.empty() || matrix[0].empty()) return 0; int rows = matrix.size(); int cols = matrix[0].size(); vector&lt;int&gt; heights(cols, 0); // 每列的高度 int maxArea = 0; for (int row = 0; row &lt; rows; ++row) { // 更新高度数组 for (int col = 0; col &lt; cols; ++col) { if (matrix[row][col] == &#39;1&#39;) { heights[col] += 1; } else { heights[col] = 0; } } // 使用 LeetCode 84 的方法计算当前行的最大面积 maxArea = max(maxArea, largestRectangleArea(heights)); } return maxArea; } // 主函数测试 int main() { vector&lt;vector&lt;char&gt;&gt; matrix = { {&#39;1&#39;,&#39;0&#39;,&#39;1&#39;,&#39;0&#39;,&#39;0&#39;}, {&#39;1&#39;,&#39;0&#39;,&#39;1&#39;,&#39;1&#39;,&#39;1&#39;}, {&#39;1&#39;,&#39;1&#39;,&#39;1&#39;,&#39;1&#39;,&#39;1&#39;}, {&#39;1&#39;,&#39;0&#39;,&#39;0&#39;,&#39;1&#39;,&#39;0&#39;} }; cout &lt;&lt; &quot;最大矩形面积是: &quot; &lt;&lt; maximalRectangle(matrix) &lt;&lt; endl; return 0; } ``` --- ### 🔹代码解释: - `largestRectangleArea`:使用单调栈实现 LeetCode 84 的解法。 - `maximalRectangle`: - 遍历每一行,维护一个 `heights` 数组,表示当前行以上每列的&ldquo;高度&rdquo;。 - 每一行都调用一次 `largestRectangleArea` 来计算最大矩形面积。 - 时间复杂度:`O(rows * cols)`,因为每一行构建高度数组是 `O(cols)`,而单调栈也是 `O(cols)`。 --- ### 🔹总结: | 项目 | 内容 | |------|------| | 难度 | 困难 | | 算法 | 单调栈 + 动态规划 | | 时间复杂度 | O(rows &times; cols) | | 空间复杂度 | O(cols) | | 相关题号 | LeetCode 84, 221(最大正方形) | --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值