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; } };