leetcode 1277

今天做了一道dp的题,感觉和今年中科大夏令营上机题神似,题目如下(来自leetcode):
在这里插入图片描述

我的思路是设置一个二维数组dp,来保存一些信息。这个dp[i][j]保存的是什么呢?是以点 (i,j) 为正方形右下角顶点所能组成的正方形变成。例如上图的示例1,有:

dp=
[
    [0,1,1,1],
    [1,1,2,2],
    [0,1,2,3]
]

那么我们最终要计算的的就是数组dp的和。因此问题转化成了如何求dp。

当 matrix[i][j] == 0,显然 dp[i][j] == 0,因为如果以点 (i,j) 为一个正方形的右下角,肯定是构不成正方形的;

当 matrix[i][j] == 1,且i == 0或j == 0时,dp[i][j]==1;

当 matrix[i][j] == 1,且i > 0和j > 0时,需要从点 (i,j) 出发,向上和左方向去搜索 dp[i-1][j-1] 个单位,如果遇到0则跳出,反之不断加1。

AC代码如下:

class Solution {
public:
    int countSquares(vector<vector<int>>& matrix) {
        int n = matrix.size();
        int m = matrix[0].size();
        vector<vector<int>> dp(n,vector<int>(m,0));
        int cnt = 0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
            	//原矩阵数值为0,则dp为0
                if(matrix[i][j]==0)
                {
                    dp[i][j] = 0;
                }
                //原矩阵数值为1,先令dp为1
                else if(matrix[i][j]==1)
                {
                    dp[i][j] = 1;
                }
                //如果原矩阵点的值为1,且该点上侧和左侧非空
                if(i>=1&&j>=1&&matrix[i][j]==1)
                {
                	//分别向上和向左搜索dp[i-1][j-1]个单位
                    for(int k=1;k<=dp[i-1][j-1];k++)
                    {
                    	//如果上侧和左侧的值都为1,则dp自增1
                        if(matrix[i-k][j]==1&&matrix[i][j-k]==1)
                        {
                            dp[i][j]++;
                        }
                        //遇到0跳出
                        else
                        {
                            break;
                        }
                    }
                }
                cnt += dp[i][j];
            }
        }
        return cnt;
    }
};
发布了34 篇原创文章 · 获赞 80 · 访问量 2013

猜你喜欢

转载自blog.csdn.net/jackzhang11/article/details/103564355
今日推荐