Maximal Square

1. 解析

题目大意,从矩阵当中选择面积最大的正方形区域

2. 分析

刚开始看的时候,我也以为跟Surrounded Regions这道题一样,当本题不同在于正方形是个固定的区域,并不是任意发散的,所以本质上这两道题的思路还是不一样的。先解析一种暴力破解的方式,也比较容易理解,用counter数组记录每个列'1'出现的个数,如果是连续出现,即可以认为是长度。

例如 [ [1 0 1 0 0], [1 0 1 1 1], [1 1 1 1 1], [1 0 0 1 0]],从区域第1行至最后一行进行检索,首先检索第一行[ [1 0 1 0 0] ],记录列中出现'1'的个数,宽是确定的,即为当前检索的行 减  起始行 即为1,若当前列连续出现1的长度等于宽,即为正方形区域;接着,检索范围扩大到第二行,[ [1 0 1 0 0], [1 0 1 1 1] ] ,采取同样的方式,如果当前能检测到正方形区域,则更新最大值

第一轮检测区域范围为第1行至第4行[1, 4]: [1, 1]——>[1, 2]——>[1, 3]——>[1, 4]

第二轮检测区域范围为[2, 4]: [2, 2]——>[2, 3]——>[2, 4]

......

class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        int res = 0;
        for (int row = 0; row < matrix.size(); ++row){
            vector<int> counter(matrix[row].size(), 0);
            for (int c_row = row; c_row < matrix.size(); ++c_row){
                for (int col = 0; col < matrix[c_row].size(); ++col){
                    if (matrix[c_row][col] == '1') counter[col]++; //记录可能的长
                }
                res = max(res, getArea(counter, c_row-row+1));
            }
        }
        return res;
    }
     
    int getArea(vector<int>& counter, int side_len){ //side_len---宽
        if (counter.size() < side_len) return 0;
        int count = 0;
        for (int col = 0; col < counter.size(); ++col){
            if (counter[col] == side_len) count++; //求解区域相邻的长
            else count = 0;
            if (count == side_len) return side_len * side_len; //正方形区域,即长和宽一样
        }
        return 0;
    }
};

3.  动态规划解法 

本题考查的核心,应该就是动态规划,仔细分析,就会发现,若将正方形区域的右下角坐标即为(row, col),则该正方形区域的边长取决于(row, col-1), (row+1, col),(row-1, col-1)的最小值。所以我们可以用二维数组dp[row][col]表示在matrix矩阵当中的该位置所包含的最大正方形区域面积,则状态转移方程为dp[row][col] = min(dp[row][col-1], dp[row-1][col], dp[row-1][col-1] ),当row或者col为0时,dp[row][col] = matrix[row][col] - '0';

class Solution {
public:
    int maximalSquare(vector<vector<char>>& matrix) {
        if (matrix.empty() || matrix[0].empty()) return  0;
        int res = 0;
        int m = matrix.size(), n = matrix[0].size();
        vector<vector<int>> dp(m, vector<int>(n, 0));

        for (int row = 0; row < m; ++row){
            for (int col = 0; col < n; ++col){
                if (row == 0 || col == 0)
                    dp[row][col] = matrix[row][col] - '0';
                else if (matrix[row][col] == '1')
                    dp[row][col] = min(dp[row-1][col-1], min(dp[row-1][col], dp[row][col-1])) +1;
                res = max(res, dp[row][col]);
            }
        }
        
        return res * res;
    }
};

 [1]https://www.cnblogs.com/grandyang/p/4550604.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值