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.
利用一個3維的vector去紀錄所有情形到目前為止的數量,第一個維度代表row,第二個維度代表col,第三個維度: 0代表horizontal的結果,1代表vertical的結果,2代表對角線的結果,3代表反對角線的結果。
// Dynamic Programming
int longestLine(vector<vector<int>>& M) { // time: O(m * n); space: O(m * n)
if (M.empty() || M[0].empty()) return 0;
int m = M.size(), n = M[0].size(), res = 0;
vector<vector<vector<int> > > dp(m, vector<vector<int> >(n, vector<int>(4, 0) ) );
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (M[i][j] == 0) continue;
for(int k = 0; k < 4; ++k) dp[i][j][k] = 1; // update
if (j > 0) dp[i][j][0] += dp[i][j - 1][0]; // horizontal
if (i > 0) dp[i][j][1] += dp[i - 1][j][1]; // vertical
if (i > 0 && j > 0) dp[i][j][2] += dp[i - 1][j - 1][2]; // diagonal
if (i > 0 && j < n - 1) dp[i][j][3] += dp[i - 1][j + 1][3]; // anti-diagonal
res = max({res, dp[i][j][0], dp[i][j][1], dp[i][j][2], dp[i][j][3]});
}
}
return res;
}
最外層的for loop是row的loop,所以可以用一個row參數來記錄水平的結果,搭配其他3個arrays分別紀錄垂直、對角線、反對角線的結果。
// Dynamic Programming with Optimized Space Usage
int longestLine(vector<vector<int>>& M) { // time: O(m * n); space: O(m + n)
if (M.empty() || M[0].empty()) return 0;
int m = M.size(), n = M[0].size(), res = 0;
vector<int> col(n, 0), diag(m + n - 1, 0), anti(m + n - 1, 0);
for (int i = 0; i < m; ++i) {
int row = 0;
for (int j = 0; j < n; ++j) {
if (M[i][j] == 1) {
res = max(res, ++row);
res = max(res, ++col[j]);
res = max(res, ++diag[i + j]);
res = max(res, ++anti[j - i + m - 1]);
} else {
row = 0;
col[j] = 0;
diag[i + j] = 0;
anti[j - i + m - 1] = 0;
}
}
}
return res;
}
空間最優化的解,分別對水平和垂直寫各自的nested for loops,然後再寫對角線的,對角線外層for loop是第k條正反對角線的意思。
// Optimized Space Method
int longestLine(vector<vector<int>>& M) { // time: O(m * n); space: O(1)
if (M.empty() || M[0].empty()) return 0;
int m = M.size(), n = M[0].size(), res = 0, row = 0, col = 0, diag = 0, anti = 0;
// Horizontal
for (int i = 0; i < m; ++i) {
for (int j = 0, row = 0; j < n; ++j) {
row = M[i][j] ? (row + 1) : 0;
res = max(res, row);
}
}
// Vertical
for (int j = 0; j < n; ++j) {
for (int i = 0, col = 0; i < m; ++i) {
col = M[i][j] ? (col + 1) : 0;
res = max(res, col);
}
}
for (int k = 0; k < m + n; ++k, diag = 0, anti = 0) {
// Diagonal
for (int i = max(m - 1 - k, 0), j = max(0, k - m + 1); i < m && j < n; ++i, ++j) {
diag = M[i][j] ? (diag + 1) : 0;
res = max(res, diag);
}
// Anti-diagonal
for (int i = min(k, m - 1), j = max(0, k - m + 1); i >= 0 && j < n; --i, ++j) {
anti = M[i][j] ? (anti + 1) : 0;
res = max(res, anti);
}
}
return res;
}
Last updated
Was this helpful?