Longest Line of Consecutive One in Matrix

Given a 01 matrix M, find the longest line of consecutive one in the matrix. The line could be horizontal, vertical, diagonal or anti-diagonal.

Example:
Input:
[[0,1,1,0],
[0,1,1,0],
[0,0,0,1]]
Output: 3
Hint: The number of elements in the given matrix will not exceed 10,000.
翻译自:这里写链接内容

1. 暴力搜索

分别从水平方向,竖直方向,对角线和反对角线计算。

class Solution {
public:
    int longestLine(vector<vector<int>>& M) {
        int max1=0;
        int i,j,m=M.size();
        if(!m) return 0;
        int n=M[0].size();
        for(i=0;i<m;i++){
            int b=0;
            for(j=0;j<n;j++)
            if(M[i][j]==1) {
                b++;
                max1=max(max1,b);
            }
            else b=0;

        }
        for(i=0;i<n;i++){
            int b=0;
            for(j=0;j<m;j++)
            if(M[j][i]==1) {
                b++;
                max1=max(max1,b);
            }
            else b=0;

        }
        //对角线
        for(i=0;i<m;i++){
            int b=0;j=0;int x=i;
            while(x<m&&j<n){
                if(M[x][j]==1) {
                    b++;
                    max1=max(max1,b);
                }
                else b=0;
                x++;j++;
            }

        }
        for(j=1;j<n;j++){
            int b=0;i=0;int y=j;
            while(i<m&&y<n){
                if(M[i][y]==1) {
                    b++;
                    max1=max(max1,b);
                }
                else b=0;
                i++;y++;
            }

        }
        //反对角线
        for(j=0;j<n;j++){
            int b=0;i=0;int y=j;
            while(i>=0&&i<m&&y>=0&&y<n){
                if(M[i][y]==1) {
                    b++;
                    max1=max(max1,b);
                }
                else b=0;
                y--;i++;
            }

        }
       for(i=1;i<m;i++){
            int b=0;j=n-1;int x=i;
            while(x<m&&j>=0){
                if(M[x][j]==1) {
                    b++;
                    max1=max(max1,b);
                }
                else b=0;
                j--;x++;
            }

        }
        return max1;
    }
};

2. 3维的动态规划

定义一个 mn4 的数组空间,分别用来记录四个不同方向的连续1的个数。当遍历到元素M[i][j]时,dp[i][j][0]代表以M[i][j]为最右下角元素时,所得到的水平方向连续1的个数,其他以此类推。

[0,1,1,0],
[0,1,1,0],
[0,0,0,1], 为例。
这里写图片描述
dp[0]代表水平方向, dp[1]代表竖直方向,dp[2]代表对角线方向,dp[3]代表反对角线方向。

int longestLine(vector<vector<int>>& M) {
        int max1=0;
        int i,j,m=M.size();
        if(!m) return 0;
        int n=M[0].size();
        vector<vector<vector<int>>> dp(m,vector<vector<int>> (n,vector<int>(4,0)));
        for(i=0;i<m;i++){
            for(j=0;j<n;j++){
                if(M[i][j]==1){
                    dp[i][j][0]=j>0?dp[i][j-1][0]+1:1;
                    dp[i][j][1]=i>0?dp[i-1][j][1]+1:1;
                    dp[i][j][2]=(j>0&&i>0)?dp[i-1][j-1][2]+1:1;
                    dp[i][j][3]=(i>0&&j<n-1)?dp[i-1][j+1][3]+1:1;
                }
                max1=max(max1,max(dp[i][j][0],max(dp[i][j][1],max(dp[i][j][2],dp[i][j][3]))));
            }
        }
        return max1;
    }

时间复杂度: O(mn)
空间复杂度: O(mn)

3. 2维的动态规划

观察2中动态规划的解过程,可以发现当前行的dp只依赖于其前一行的dp值。因此可以只用一个二维的 n4 的空间记录即可。

j-1列j列j+1列…….
213…….
0待处理位置…..

当你遍历到待处理位置时,此时的dp[][]存储的是它的上一行的dp状态,因为dp的长度为n,2位置除外。此时,
dp[j][0]取决于0位置的dp[j-1][0];(水平)
dp[j][1]取决于1位置的dp[j][1];(竖直)
dp[j][2]取决于2位置的dp[j][2],这里用old表示。因为当前的dp[j][2]是下一个位置要用到的old,记得保存;(正对角线)
dp[j][3]取决于3位置的dp[j+1][3]。(反对角线)

class Solution {
public:
    int longestLine(vector<vector<int>>& M) {
        int max1=0;
        int i,j,m=M.size();
        if(!m) return 0;
        int n=M[0].size();
        vector<vector<int>> dp(n,vector<int>(4,0));
        for(i=0;i<m;i++){
            int old=0;
            for(j=0;j<n;j++){
                if(M[i][j]==1){
                    dp[j][0]=j>0?dp[j-1][0]+1:1;
                    dp[j][1]=i>0?dp[j][1]+1:1;
                    int pre=dp[j][2];
                    dp[j][2]=(j>0&&i>0)?old+1:1;
                    old=pre;
                    dp[j][3]=(i>0&&j<n-1)?dp[j+1][3]+1:1;
                }else{
                    old=dp[j][2];
                    dp[j][0]=dp[j][1]=dp[j][2]=dp[j][3]=0;
                }
                max1=max(max1,max(dp[j][0],max(dp[j][1],max(dp[j][2],dp[j][3]))));
            }
        }
        return max1;
    }
};

时间复杂度: O(mn)
空间复杂度: O(n)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值