[LeetCode] Maximal Square(!!!!DP优化)

7 篇文章 0 订阅

定义一个D[i][j] 表示的是以i,j为右下角的最大子正方形的边长。这个边长是受限于D[i-1][j],D[i][j-1] ,D[i-1][j-1]中最小的那个的。

class Solution {
public:
    int maximalSquare(vector<vector<char>>& A) {
        int m = A.size();   if(m==0)    return 0;
        int n = A[0].size();    if(n==0)    return 0;
        vector< vector<int> > D(m, vector<int>(n,0));
        int max_area=0;
        for(int i = 0; i<n; ++i){
            D[0][i]=A[0][i]-'0';
            if(A[0][i]=='1')
                max_area=1;
        }
        for(int i = 0; i<m; ++i){
            D[i][0]=A[i][0]-'0';
            if(A[i][0]=='1')
                max_area=1;
        }
        for(int i =1; i<m; ++i)
            for(int j =1; j<n; ++j)
                    if(A[i][j]=='1'){
                        D[i][j]= min(min(D[i-1][j-1],D[i-1][j]),D[i][j-1])+1;
                        max_area = max(max_area, D[i][j]);
                    }
        return max_area*max_area;

    }
};

12ms AC

这里的方法需要两次初始化,代码可以被进一步优化。因为每次D[i][j]的求解 只依赖于D[i-1][j],D[i][j-1] ,D[i-1][j-1],所以实际上可以只维护两个行向量或列向量,这样空间复杂度变成了O(2m)或O(2n)

class Solution {
public:
    int maximalSquare(vector<vector<char>>& A) {
        int m = A.size();   if(m==0)    return 0;
        int n = A[0].size();    if(n==0)    return 0;
        vector<int> pre(n,0);
        vector<int> curr(n,0);
        int max_area=0;
        for(int i=0; i<n; ++i){
            pre[i]=A[0][i]-'0';
            if(A[0][i]=='1')
                max_area = 1;
        }
        for(int i =1; i<m; ++i){
            curr[0]=A[i][0]-'0';
            for(int j = 1; j<n; ++j)
                    if(A[i][j]=='1'){
                        curr[j]= min(min(pre[j-1],pre[j]),curr[j-1])+1;
                        max_area = max(max_area, curr[j]);
                    }
            //swap(pre,curr);
            //curr=vector<int>(n,0);
            pre.swap(curr);
            fill(curr.begin(),curr.end(),0);

        }
        return max_area*max_area;

    }
};

上面的swap(两种swap都是可以的)操作查了下是常数级的时间复杂度,它不涉及到元素的复制、移动、交换操作。这样的方式和使用指针的效果是相同的。

其实进一步优化可以将空间复杂度降低到O(m)

int maximalSquare(vector<vector<char>>& matrix) {
    if (matrix.empty()) return 0;
    int m = matrix.size(), n = matrix[0].size();
    vector<int> dp(m + 1, 0);
    int maxsize = 0, pre = 0;
    for (int j = 0; j < n; j++) {
        for (int i = 1; i <= m; i++) {
            int temp = dp[i];
            if (matrix[i - 1][j] == '1') {
                dp[i] = min(dp[i], min(dp[i - 1], pre)) + 1;
                maxsize = max(maxsize, dp[i]);
            }
            else dp[i] = 0; 
            pre = temp;
        }
    }
    return maxsize * maxsize;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值