zoukankan      html  css  js  c++  java
  • LC 562. 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.

    Median的题就是简单一点。

    1. DFS没有问题。

    2. 怎么保存已经遍历过的点,因为每一个点可能有4个方向,所以可以开一个map记录每一个点的四个方向有没有被经过。

    我的思路,Runtime有点慢。

    Runtime: 88 ms, faster than 13.53% of C++ online submissions for Longest Line of Consecutive One in Matrix.

    #define ALL(x) (x).begin(), (x).end()
    #define FOR(i, a, b) for (remove_cv<remove_reference<decltype(b)>::type>::type i = (a); i < (b); i++)
    #define REP(i, n) FOR(i, 0, n)
    #include <vector>
    #include <unordered_map>
    using namespace std;
    class Solution {
    private:
      unordered_map<int, vector<bool>> mp;
      int dirs[4][2] = {{1,0},{1,1},{0,1},{1,-1}};
      int n,m;
    public:
        int longestLine(vector<vector<int>>& M) {
          n = M.size();
          m = M[0].size();
          int ret;
          REP(i,n){
            REP(j,m){
              mp[i*m+j] = {false,false,false,false};
            }
          }
          REP(i,n){
            REP(j,m){
              if(M[i][j] == 1){
                dfs(M, i, j, ret);
              }
            }
          }
          return ret;      
        }
      bool valid(int x, int y){
        return x < n && x >= 0 && y < m && y >= 0;
      }
      
      void dfs(vector<vector<int>>& M, int x, int y, int& ret){
        if(x < 0 || y < 0 || x >= n || y >= m) return ;
        if(M[x][y] == 0) return ;
        REP(i, 4){
          if(mp[x*m+y][i]) continue;
          mp[x*m+y][i] = true;
          int tmpx = x, tmpy = y, dx = dirs[i][0], dy = dirs[i][1];
          int cnt = 1;
          while(valid(tmpx+dx,tmpy+dy) && M[tmpx+dx][tmpy+dy] == 1){
            tmpx += dx;tmpy += dy;
            mp[tmpx*m+tmpy][i] = true;
            cnt++;
          }
          tmpx = x, tmpy = y, dx = -dirs[i][0], dy = -dirs[i][1];
          while(valid(tmpx+dx,tmpy+dy) && M[tmpx+dx][tmpy+dy] == 1){
            tmpx += dx; tmpy += dy;
            mp[tmpx*m+tmpy][i] = true;
            cnt++;
          }
          ret = max(ret, cnt);
        }
      }
    };
    //[[0,1,1,0],
     //[0,1,1,0],
     //[0,0,0,1]]
    
    int main(){
      vector<vector<int>> M {{0,1,1,0},{0,1,1,0},{0,0,0,1}};
      return 0;
    }

    另一个思路使用dp,dp的精髓在于前后的状态无关,有点类似马尔可夫链。

    从矩阵第一行向下遍历,每一次保存的就是当前点四个方向的最大长度,如果点是1,该方向加1。也是很好的思路。

    class Solution {
        
    public:
        int longestLine(vector<vector<int>>& M) 
        {
            int r=M.size();
            if(r==0) return 0;
            int c=M[0].size();
            vector<vector<vector<int> > > dp(r,vector<vector<int>> (c,vector<int>(4,0) ) );
            int res=0;
            for(int i=0;i<r;i++)
                for(int j=0;j<c;j++)
                {
                    if(M[i][j])
                    {
                        dp[i][j][0]=j?dp[i][j-1][0]+1:1;
                        dp[i][j][1]=i?dp[i-1][j][1]+1:1;
                        dp[i][j][2]=i&&j?dp[i-1][j-1][2]+1:1;
                        dp[i][j][3]=i>0&&j<c-1?dp[i-1][j+1][3]+1:1;
                        for(auto x:dp[i][j])
                            res=max(res,x);
                    }
                }
            
            return res;
        }
    };
  • 相关阅读:
    postman接口测试及断言
    postman使用CSV和Json文件实现批量接口测试
    php 实现抽奖代码
    判断时间是否过期
    文件上传-图片展示
    导入
    增删改查
    NDK编译Eigen
    keras下载vgg16太慢解决办法
    非极大值抑制NMS
  • 原文地址:https://www.cnblogs.com/ethanhong/p/10168558.html
Copyright © 2011-2022 走看看