import java.util.*; /** * Find the longest increasing(increasing means one step) sequence in an * integer matrix in 4 directions (up down left right), return the sequence * * For Example: * |1 2 3 4| * |8 7 6 5| * * Output: * [1, 2, 3, 4, 5, 6, 7, 8] * * Tags: DP, DFS */ class LongestIncreasingSequenceInMat { public static void main(String[] args) { LongestIncreasingSequenceInMat l = new LongestIncreasingSequenceInMat(); int[][] mat = { {1, 2, 3, 4}, {8, 7, 6, 5}, {9, 10, 11, 12} }; System.out.println(Arrays.toString(l.longest(mat))); } public static final int[][] DIRS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; int[][] cache; /** * DP * d[i][j] = max{d[i+1][j], d[i-1][j], d[i][j+1], d[i][j-1]} + 1 */ public int[] longest(int[][] mat) { int[] res = new int[]{}; if (mat == null || mat.length == 0 || mat[0].length == 0) return res; int m = mat.length; int n = mat[0].length; cache = new int[m][n]; int maxStart = 0; int maxPath = 0; for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) { int path = dfs(i, j, mat); if (path > maxPath) { maxStart = mat[i][j]; maxPath = path; } } res = new int[maxPath]; // TODO recover the path, from maxStart with maxPath for (int i = 0; i < maxPath; i++) res[i] = maxStart + i; return res; } private int dfs(int i, int j, int[][] mat) { if (cache[i][j] != 0) return cache[i][j]; // has cache int m = mat.length; int n = mat[0].length; for (int[] d : DIRS) { // search 4 directions int ni = i + d[0]; // get next coordinates int nj = j + d[1]; if (ni >= 0 && ni < m && nj >= 0 && nj < n && mat[ni][nj] == mat[i][j] + 1) { // if dfs(ni, nj) is bigger, update cache[i][j] cache[i][j] = Math.max(cache[i][j], dfs(ni, nj, mat)); } } return ++cache[i][j]; // add cache[i][j] by 1 and return! } }