931.给你一个 n x n 的 方形 整数数组 matrix ,请你找出并返回通过 matrix 的下降路径 的 最小和 。
下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。具体来说,位置 (row, col) 的下一个元素应当是 (row + 1, col - 1)、(row + 1, col) 或者 (row + 1, col + 1) 。
示例 1:
输入:matrix = [[2,1,3],[6,5,4],[7,8,9]]
输出:13
解释: 1 -> 4 -> 8
- 首先纯套公式:假设 f(i,j) 为到达 (i,j) 的最小和。分析情况可以得到,如果 j = 0,只能从上和右上取最小值,如果 j=n-1,只能从上和左上取最小值,否则就是取上,左上和右上的最小值,当然别忘了如果 n = 1,那么只有一条路,直接返回这条路径的和即可。
-
int max = Integer.MAX_VALUE; public int minFallingPathSum(int[][] matrix) { int n = matrix[0].length; int[][] f = new int[n][n]; int ans = max; for(int i = 0; i < n; i++){ for(int j = 0; j < n; j++){ if(i == 0){ f[i][j] = matrix[i][j]; }else if(j == 0){ f[i][j] = matrix[i][j] + Math.min(f[i-1][j],f[i-1][j+1]); }else if(j == n-1){ f[i][j] = matrix[i][j] + Math.min(f[i-1][j-1],f[i-1][j]); }else{ int topLeft = f[i-1][j-1]; int top = f[i-1][j]; int topRight = f[i-1][j+1]; int min = topLeft <= top? topLeft : top; min = topRight <= min? topRight : min; f[i][j] = matrix[i][j] + min; } if(i == n-1){ ans = Math.min(ans,f[i][j]); } } } return n > 1? ans : matrix[0][0]; }
- 不难看出,这里也同样可以利用 matrix 的空间来存储路径和
-
int max = Integer.MAX_VALUE; public int minFallingPathSum(int[][] matrix) { int n = matrix.length; int ans = max; for(int i = 1; i < n; i++){ for(int j = 0; j < n; j++){ if(j == 0){ matrix[i][j] = matrix[i][j] + Math.min(matrix[i-1][j],matrix[i-1][j+1]); }else if(j == n-1){ matrix[i][j] = matrix[i][j] + Math.min(matrix[i-1][j-1],matrix[i-1][j]); }else{ int topLeft = matrix[i-1][j-1]; int top = matrix[i-1][j]; int topRight = matrix[i-1][j+1]; int min = topLeft <= top? topLeft : top; min = topRight <= min? topRight : min; matrix[i][j] = matrix[i][j] + min; } if(i == n-1){ ans = Math.min(ans,matrix[i][j]); } } } return n > 1? ans : matrix[0][0]; }