【leetcode】221 最大正方形(动态规划)

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

题目描述

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

示例:

输入: 

1 0 1 0 0
1 0 1 1 1
1 1 1 1 1
1 0 0 1 0

输出: 4

思路

动态规划问题。设二维数组dp[m][n],其中dp[i][j]表示以坐标(i,j)为右下角元素的最大正方形的边长。

通过观察我们可以看出当前位置的最大正方形边长为上,左,左上三个位置最大正方形边长的最小值+1。(必须这三个正方形同时满足&&该位置matrix[i][j]==1 的条件下,最大边长)

得到动态规划方程:
如果 matrix[i][j] == 1

dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i-1][j-1]) + 1

否则

dp[i][j] = 0

并用一个变量maxLen记录下遍历过程中的最大正方形边长,最终返回maxLen*maxLen为最大正方形面积。

复杂度分析
时间复杂度:O(mn)
空间复杂度:O(mn)
m,n为输入矩阵的行列数。

代码

/*
 * 动态规划
 * 时间复杂度O(mn) 空间复杂度O(mn)
 */
class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        if(matrix.empty() || matrix[0].empty()) return 0;

        int rows = matrix.size(), cols = matrix[0].size();
        vector<vector<int >> dp(rows, vector<int>(cols,0));     // dp[i][j]表示以坐标i,j作为右下角的最大矩形边长
        int maxLen = 0;
        // 初始化第一行
        for (int i = 0; i < rows; ++i) {
            dp[i][0] = matrix[i][0] - '0';
            maxLen = max(maxLen,dp[i][0]);
        }
        // 初始化第一列
        for (int j = 0; j < cols; ++j) {
            dp[0][j] = matrix[0][j] - '0';
            maxLen = max(maxLen,dp[0][j]);
        }
        for (int i = 1; i < rows; ++i) {
            for (int j = 1; j < cols; ++j) {
                if (matrix[i][j]=='0') continue;  // 面积为0
                int len1 = dp[i-1][j];
                int len2 = dp[i][j-1];
                int len3 = dp[i-1][j-1];
                dp[i][j] = min(min(len1,len2),len3) + 1;    // 满足条件的最大边长
                maxLen = max(dp[i][j], maxLen);
            }
        }
        return maxLen*maxLen;
    }
};

【leetcode】221 最大正方形(动态规划)_第1张图片

你可能感兴趣的:(LeetCode)