Given an integer matrix. Find the longest increasing continuous subsequence in this matrix and return the length of it.
The longest increasing continuous subsequence here can start at any position and go up/down/left/right.
Example
Example 1:
Input:
[
[1, 2, 3, 4, 5],
[16,17,24,23,6],
[15,18,25,22,7],
[14,19,20,21,8],
[13,12,11,10,9]
]
Output: 25
Explanation: 1 -> 2 -> 3 -> 4 -> 5 -> ... -> 25 (Spiral from outside to inside.)
Example 2:
Input:
[
[1, 2],
[5, 3]
]
Output: 4
Explanation: 1 -> 2 -> 3 -> 5
Challenge
Assume that it is a N x M matrix. Solve this problem in O(NM) time and memory.
思路1:按照类似于Trapping Rain Water II 的思路,从最小的点开始走,每次poll最小的点,然后根据四个邻居来更新dp[i][j] ,最后求个全局的最大值即可。m*n*long(m*n);
public class Solution {
/**
* @param matrix: A 2D-array of integers
* @return: an integer
*/
private class Node {
public int x;
public int y;
public int value;
public Node(int x, int y, int value) {
this.x = x;
this.y = y;
this.value = value;
}
}
public int longestContinuousIncreasingSubsequence2(int[][] matrix) {
if(matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return 0;
}
int m = matrix.length;
int n = matrix[0].length;
PriorityQueue<Node> pq = new PriorityQueue<Node>((a, b) -> (a.value - b.value));
int[][] dp = new int[m][n];
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
dp[i][j] = 1;
pq.offer(new Node(i, j, matrix[i][j]));
}
}
int[][] dirs = {{0,1},{0,-1}, {-1,0},{1,0}};
int globalmax = 1;
while(!pq.isEmpty()) {
Node node = pq.poll();
int x = node.x;
int y = node.y;
for(int[] dir: dirs) {
int nx = x + dir[0];
int ny = y + dir[1];
if(0 <= nx && nx < m && 0 <= ny && ny < n && matrix[nx][ny] < matrix[x][y]) {
dp[x][y] = Math.max(dp[x][y], dp[nx][ny] + 1);
}
}
globalmax = Math.max(globalmax, dp[x][y]);
}
return globalmax;
}
}
思路2:在每个点做dfs,去求当前的length,dfs可以用cache加速。
public class Solution {
/**
* @param matrix: A 2D-array of integers
* @return: an integer
*/
public int longestContinuousIncreasingSubsequence2(int[][] matrix) {
if(matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return 0;
}
int m = matrix.length;
int n = matrix[0].length;
int[][] dp = new int[m][n];
for(int i = 0; i < m; i++) {
Arrays.fill(dp[i], -1);
}
int globalmax = 0;
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
globalmax = Math.max(globalmax, dfs(matrix, i, j, dp));
}
}
return globalmax;
}
private int[][] dirs = {{0,1},{0,-1},{-1,0},{1,0}};
private int dfs(int[][] matrix, int x, int y, int[][] dp) {
int m = matrix.length;
int n = matrix[0].length;
if(dp[x][y] != -1) {
return dp[x][y];
}
dp[x][y] = 1;
for(int[] dir: dirs) {
int nx = x + dir[0];
int ny = y + dir[1];
if(0 <= nx && nx < m && 0 <= ny && ny < n && matrix[nx][ny] < matrix[x][y]) {
int neighborlength = dfs(matrix, nx, ny, dp);
dp[x][y] = Math.max(dp[x][y], neighborlength + 1);
}
}
return dp[x][y];
}
}