首页 > 其他分享 >1277. 统计全为 1 的正方形子矩阵

1277. 统计全为 1 的正方形子矩阵

时间:2023-10-15 23:32:58浏览次数:43  
标签:cnt matrix int 矩阵 ++ 1277 正方形 dp size

解法1:比较好理解的方式

dp[i][j][k]: 以 (i, j) 为右下角,长度为k的正方形是否满足全都为1,满足则为1,不满足则为0 我们要做的就是对每个点判断一下它可能长度的正方形是不是以下几个条件:

  1. 本身是否为1
  2. dp [i - 1] [j] [k - 1]是否为1
  3. dp [i] [j - 1] [k - 1]是否为1
  4. dp [i - 1] [j - 1] [k - 1]是否为1

这几个条件画个图就明白是怎么来的了

class Solution {
public:
    int countSquares(vector<vector<int>>& matrix) {
        if(matrix.empty()) return 0;
        int m = matrix.size();
        int n = matrix[0].size();
        int z = min(m, n) + 10;
        int dp[m][n][z], cnt = 0;
        int row = matrix.size();
        int col = matrix[0].size();

        for(int i = 0; i < row; ++i)
        {
            for(int j = 0; j < col; ++j)
            {
                dp[i][j][1] = matrix[i][j];
                if(dp[i][j][1]) ++cnt;
            }
        } 
        
        for(int i = 1; i < row; ++i)
        {
            for(int j = 1; j < col; ++j)
            {
                for(int k = 2; k <= min(i, j) + 1; ++k)
                {
                    if(matrix[i][j] && dp[i - 1][j][k - 1] && dp[i][j - 1][k - 1] && dp[i - 1][j - 1][k - 1])
                        dp[i][j][k] = 1, ++cnt;
                    else 
                        dp[i][j][k] = 0;
                }
            }
        }

        return cnt;
    }
};

解法2:其实是对上面的优化

优化是怎么来的呢? 假设我们现在判断(2, 2)这个点,会分别判断边长为1,2,3是不是满足题意,但是如果它最大是个边长为3的正方形,边长为1,2判断出来就一定是满足的,那我们那两次判断完全就没有什么必要,只需要求出这个3,能够组成的正方形数量通过数学计算就可以得到,也就是我们可以省略掉k那一维度。 首先我们来确定以下dp[][]数组的含义是什么? 从上面的分析可以看出,我们的主要目标就是找到那个3,也就是以(i, j)为右下角的正方形的最大边长,所以数组的含义自然就是这个。 接下来就需要确定状态转移方程,这个就是这个问题的难点,我们如何通过之前的状态推得当前的状态,之前的状态无非就是dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1], 我觉得这个时候为他们赋个值,画个图可能会好理解一些,假设它们的值依次是1, 2, 3

在这里插入图片描述金色的部分就是以(i, j)为右下角的最大变成的正方形,就是从3个之前的状态中找到最小的然后+1得到的,其实也不难理解,就有种短板效应的意思,最大边长越短说明周边环境越苛刻,下一个状态需要考虑到全体情况,就需要满足最苛刻的条件,也就是3个之前状态中边长最短的那个。

class Solution {
public:
    int countSquares(vector<vector<int>>& matrix) {
        if(matrix.empty()) return 0;
        int m = matrix.size();
        int n = matrix[0].size();
        int z = min(m, n) + 10;
        int dp[m][n], cnt = 0;
        int row = matrix.size();
        int col = matrix[0].size();

        for(int i = 0; i < col; ++i) dp[0][i] = matrix[0][i], cnt += dp[0][i];
        for(int i = 1; i < row; ++i) dp[i][0] = matrix[i][0], cnt += dp[i][0];
        
        for(int i = 1; i < row; ++i)
        {
            for(int j = 1; j < col; ++j)
            {
                if(matrix[i][j])
                {
                    dp[i][j] = min(min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;
                    cnt += dp[i][j];
                }
                else 
                    dp[i][j] = 0;
            }
        }

        return cnt;
    }
};

标签:cnt,matrix,int,矩阵,++,1277,正方形,dp,size
From: https://blog.51cto.com/u_14882565/7874035

相关文章

  • LeetCode59. 螺旋矩阵Ⅱ
    题目描述给你一个正整数n,生成一个包含1到n2所有元素,且元素按顺时针顺序螺旋排列的nxn正方形矩阵matrix。示例提交的代码classSolution{intmatrixLen=0;publicint[][]generateMatrix(intn){ //初始化空数组int[][]matrix=newint[n][......
  • 矩阵优化dp
    都快csps了,还什么都不会的菜鱼(我估计着马上就可以改了这句话了,成了都快noip了)矩阵我们要用矩阵优化dp,首先要知道矩阵是个什么东西(感觉其实可以不用知道)。矩阵的很多定义啥的都可以选择去oi-wiki上去进行学习。很简单的一堆定义。读者自学不难,这里就不多赘述。矩阵加法就是将......
  • OpenGL入门——矩阵变换与坐标系统
    一、OpenGL的数学库GLM向量和矩阵的运算就不作说明了,直接介绍OpenGL中如何使用矩阵变换。GLM(官网:OpenGLMathematics(g-truc.net))是OpenGL Mathematics的缩写,它是一个只有头文件的库,也就是说只需包含对应的头文件就行了,不用链接和编译。把头文件的根目录复制到项目的includes......
  • 行列式与矩阵树定理
    定义定义矩阵的行列式:\[\detA=\sum_{\sigma}(-1)^{\tau(\sigma)}\prod_{i=1}^nA_{i\sigma_i}\]\(\tau(\sigma)\)是原排列的逆序对数。性质:若矩阵的某一行或某一列全为\(0\),则行列式为\(0\)。\(\detA=\detA^T\)。交换\(A\)的两行或两列,行列式取反。某一行或某一......
  • python_两两比较计算相似矩阵
    距离矩阵余弦距离矩阵余弦距离使用两个向量夹角的余弦值作为衡量两个个体间差异的大小。相比欧氏距离,余弦距离更加注重两个向量在方向上的差异点集内或矩阵内两两元素之间的距离矩阵##简单使用两重循环defcompute_squared_EDM_method(X):#获得矩阵都行和列,因为是行向......
  • 代码随想录第二天|977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II
    977有序数组的平方题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/思路:双指针(实际是三指针),两个找最大值,一个确定平方后的位置。209.长度最小的子数组题目链接:https://leetcode.cn/problems/minimum-size-subarray-sum/思路:很像双指针,一个指向子数组开头,一......
  • 【noip赛前20天冲刺集训 day3】矩阵挑战
    NOIP比赛前的冲刺训练-第3天:矩阵挑战问题描述您有一个n×m矩阵,行编号从0到n−1,列编号从0到m−1。最初,第i行第j列的元素是i*m+j。系统支持三种类型的操作:交换两行。交换两列。交换两个特定的元素。任务是确定执行q次操作后矩阵的状态。输入格式为了最小化输......
  • MATLAB矩阵分析
    一、矩阵的基础知识closeall;clearall;clc;%%改变矩阵尺寸a=eye(3);a(2,4)=3;%添加第四列,第二行元素为3,其余为0a(:,4)=3;%添加第四列,元素都是3a(2,:)=[];%删除第二行a(:,2)=[];%删除第二列b=a(1:end);%将矩阵变为行向量,以列为顺序,end表示最后一个元素%%改变矩阵形状......
  • 矩阵连乘问题,生成需要的矩阵
      任务是这样子的:我们先完成txt文本矩阵的准备,大概做了50个矩阵; 代码如下:#include <iostream>#include <fstream>#include <vector>#include <random>#include <string>#include <windows.h> // 包含 Windows API 头文件// 创建文件夹(仅适用于 Window......
  • 矩阵键盘的基本操作
    矩阵键盘的基本操作1、矩阵键盘的扫描思想与独立按键不同的是,按键的两个引脚都分别连接的单片机的I/O端口,一个作为行信号,另外一个作为列信号。我们以4X4的矩阵键盘为例,试着探讨其工作方式和扫描思路。在上面的矩阵键盘中,要识别出黄色按键的按下状态,应该怎么做呢?对于矩阵键盘,......