PigyChan_LeetCode 1504. 统计全 1 子矩形

1504. 统计全 1 子矩形

给你一个只包含 0 和 1 的 rows * columns 矩阵 mat ,请你返回有多少个 子矩形 的元素全部都是 1 。

示例 1:

输入:mat = [[1,0,1],
[1,1,0],
[1,1,0]]
输出:13
解释:
有 6 个 1x1 的矩形。
有 2 个 1x2 的矩形。
有 3 个 2x1 的矩形。
有 1 个 2x2 的矩形。
有 1 个 3x1 的矩形。
矩形数目总共 = 6 + 2 + 3 + 1 + 1 = 13 。
示例 2:

输入:mat = [[0,1,1,0],
[0,1,1,1],
[1,1,1,0]]
输出:24
解释:
有 8 个 1x1 的子矩形。
有 5 个 1x2 的子矩形。
有 2 个 1x3 的子矩形。
有 4 个 2x1 的子矩形。
有 2 个 2x2 的子矩形。
有 2 个 3x1 的子矩形。
有 1 个 3x2 的子矩形。
矩形数目总共 = 8 + 5 + 2 + 4 + 2 + 2 + 1 = 24 。

思路1.0(已看题解)
将统计矩阵中全1子矩阵分为两个步骤:(1)统计每一行的全1子矩阵
(2)以压缩的方法从上往下统计剩下的全1子矩阵

在这里插入图片描述

图中是以列数r=2来进行压缩,这种按位与的压缩方法,可以使压缩后的1来映射压缩前的子矩阵是否是2x1,而两个连续的压缩后的1,即两个连续的2x1子矩阵,也就是一个2x2矩阵啦。然后只要再通过第(1)步中,统计每行的全1子矩阵的方法,然后再重复统计n=[2:4]的情况,就欧了。
代码1.0(AC):

class Solution {
public:
    int numSubmat(vector<vector<int>>& mat) {
        int row = mat.size();
        int col = mat[0].size();
        int tol = 0;
        for (int k = 0; k <row; k++)
        {
            //统计
            for (int i = k; i < row; ++i)
            {
                int sum = 0;
                for (int j = 0; j < col; ++j)
                {
                    if (mat[i][j] == 0) sum = 0;
                    else sum += mat[i][j];
                    tol += sum;
                }
            }
            //压缩
            for (int i = row - 1; i > k; --i)
            {
                for (int j = 0; j < col; ++j)
                {
                    mat[i][j] = mat[i][j] & mat[i - 1][j];
                }
            }
        }
        return tol;
    }
};

矩阵压缩这个方法很好理解,但是复杂度有点高,要多次遍历矩阵,而且好像没用到动态规划的思想,自己一上来一点思路都没有就是因为找不到用上动态规划的方法(找不到最优子结构)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值