zoukankan      html  css  js  c++  java
  • 【LeetCode-动态规划】最大正方形

    题目描述

    在一个由 0 和 1 组成的二维矩阵内,找到只包含 1 的最大正方形,并返回其面积。
    示例:

    输入: 
    1 0 1 0 0
    1 0 1 1 1
    1 1 1 1 1
    1 0 0 1 0
    
    输出: 4
    

    题目链接: https://leetcode-cn.com/problems/maximal-square/

    思路1

    暴力法。遍历二维数组,如果当前位置是 1,就把当前位置作为正方形的左上角,先计算横向边长最长是多少,假设这个长度为 len,然后以当前位置为左上角,[1, len]范围为边长,搜索小正方形内是否全为1,记录面积最大值。代码如下:

    class Solution {
    public:
        int maximalSquare(vector<vector<char>>& matrix) {
            if(matrix.empty()) return 0;
    
            int rows = matrix.size();
            int cols = matrix[0].size();
            if(cols==0) return 0;
    
            int ans = 0;
            for(int i=0; i<rows; i++){
                for(int j=0; j<cols; j++){
                    if(matrix[i][j]=='1'){
                        int k = j+1;
                        while(k<cols && matrix[i][k]=='1') k++;
                        int len = k-j;  // 当前位置边长可能的最大值
                        bool isCandi = true;    // 如果isCandi为true,说明当前的小正方形内全为1
                        for(int x=1; x<=len; x++){
                            if(i+x>rows) break;
                            else{
                                for(int r=i; r<i+x; r++){
                                    for(int c=j; c<j+x; c++){
                                        if(matrix[r][c]!='1') isCandi = false;
                                    }
                                }
                                if(isCandi) ans = max(x*x, ans);
                            }
                        }
                    }
                }
            }
            return ans;
        }
    };
    
    • 时间复杂度:O(m*n*min(m,n)^2)
      m,n 分别是矩阵的行列数。
    • 空间复杂度:O(1)

    思路2

    使用动态规划。

    • 状态定义:dp[i][j] 表示以位置 (i,j) 为右下角的全为 1 的正方形边长;
    • 状态转移方程:dp[i][j] = min(dp[i-1][j], dp[i-1][j-1], dp[i][j-1]) + 1,也就是当前位置符合条件的边长等于当前位置左边一个位置、左上角一个位置、上面一个位置符合条件边长的最小值加 1;
    • 边界条件:当只有一行或者一列时,如果 matrix[i][j] = 1, dp[i][j]=1;否则 dp[i][j]=0.

    关于状态转移方程,可以参考这篇题解的解释,如下图

    类似于木桶效应,当前位置的边长与相邻的三个位置的最小值有关。
    代码如下:

    class Solution {
    public:
        int maximalSquare(vector<vector<char>>& matrix) {
            if(matrix.empty() || matrix[0].empty()) return 0;
    
            int rows = matrix.size();
            int cols = matrix[0].size();
            vector<vector<int>> dp(rows, vector<int>(cols, 0));
            int maxLen = 0; // 符合条件正方形的最大边长
            for(int i=0; i<rows; i++){
                for(int j=0; j<cols; j++){
                    if(matrix[i][j]=='1'){
                        if(i==0 || j==0) dp[i][j] = 1;  // 边界条件
                        else{
                            dp[i][j] = min(min(dp[i-1][j], dp[i-1][j-1]), dp[i][j-1]) + 1;
                        }
                        maxLen = max(dp[i][j], maxLen);
                    }
                }
            }
            return maxLen*maxLen;
        }
    };
    
    • 时间复杂度:O(m*n)
      m,n 分别是矩阵的行列数。
    • 空间复杂度:O(m*n)
  • 相关阅读:
    List<Map>遍历相加
    jqgrid属性
    idea Could not autowire. No beans of 'xxxx' type found
    【笔记】抓取百度贴吧
    python url中文转码
    python lxml 库
    Python 基础 (笔记)
    HTML 背景
    HTML Iframe
    HTML 响应式 Web 设计
  • 原文地址:https://www.cnblogs.com/flix/p/12851781.html
Copyright © 2011-2022 走看看