import java.util.*; /** * 解题思路: (深度优先遍历 + 动态规划) * 这是一道很难,很综合类的题目,认真做完后真的会收获很多 * 首先一上来,我们肯定能想到用深度优先算法进行寻找最长递增路径,但是我们无法确定那个元素作为起点的时候, * 最长递增路径最长,因此我们只能每个元素都作为起点,求出其最长递增路径的长度,之后选取最长的即可.这样子 * 想之后,毫无疑问时间复杂度很高很高,因此我们必须想办法进行优化.同时还有一个问题就是我们在进行深度优先 * 遍历的时候,是否会出现走回路的情况(这个必须想清楚). * 首先我们考虑第二个回路的问题: 本题要求很好的避免了走回路的问题,我们不需要一个单独的矩阵来记录遍历过 * 的元素了,因为题目中要求的是递增的路径,因此我们 dfs 中每从一个元素进入下一个元素,则下一个元素一定比 * 当前元素大,且比其之前的每一个元素都大,因此不可能出现回路的情况. * 其次考虑第一个时间复杂度的问题: 我们认真思考我们的 dfs 过程,其实我们每次递归进入一个新的元素,都要 * 求出以这个元素为起点的最长递增路径,且在我们求出以每个点作为起点的最长递归路径的时候,肯定会重复求以一 * 些元素作为起点的最长递增路径,因此我们就想利用一个 dp 矩阵,对应每一次递归过程中,如果求出了以某个元素 * 作为起点的最长递增路径时,就直接填入dp数组中,且在我们的 dfs 中,递归到(row,col)元素的时候, * 若dp[row][col] != 0 ,即表示以该元素作为起点的最长递增路径我们已经求出来了,直接选用即可,不再继续 * dfs 下去,极大的减少了时间复杂度,这是典型的空间换取时间的做法. * * 本题答案中还有一个很巧妙的东西,就是实现向上下左右移动的时候,使用了一个 direction 数组来记录上下左右 * 四个方向,在 dfs 过程中直接使用循环来实现向上下左右移动,避免书写重复的代码,真的很巧妙!! */ public class Solution { private static final int[][] direction = {{-1,0},{0,1},{1,0},{0,-1}}; public int solve (int[][] matrix) { //判空处理 if (matrix == null || matrix.length == 0 || matrix[0].length == 0) { return 0; } //记录以 matrix[i][j] 为起点的最长递归路径的长度 int[][] dp = new int[matrix.length][matrix[0].length]; //记录最长递归路径的长度 int maxLen = 0; //求出以每个点作为起点的最长递归路径 for (int i = 0; i < matrix.length; i++) { for (int j = 0; j < matrix[0].length; j++) { if (dp[i][j] == 0) { dp[i][j] = dfs(matrix,dp,i,j); } maxLen = Math.max(maxLen,dp[i][j]); } } return maxLen; } /** * 深度优先搜索最长递增路径 * @param matrix 记录原数字的矩阵 * @param dp 记录以 matrix[i][j] 为起点的最长递归路径的长度的矩阵 * @param row 当前行 * @param col 当前列 * @return */ private static int dfs(int[][] matrix, int[][] dp, int row, int col) { //原先的递归遍历中已经求出过以该点为起点的最长递归路径的长度,直接用即可 if (dp[row][col] != 0) { return dp[row][col]; } int maxLen = 0; //遍历四个方向 for (int k = 0; k < 4; k++) { int i = row + direction[k][0]; int j = col + direction[k][1]; if (i >= 0 && i < matrix.length && j >= 0 && j < matrix[0].length && matrix[i][j] > matrix[row][col]) { maxLen = Math.max(maxLen,dfs(matrix,dp,i,j)); } } //别忘了当前元素也为路径中的一员 maxLen++; //维护 dp 数组 dp[row][col] = maxLen; return maxLen; } }