【举一反三】:最大路径和——数字三角形问题(动态规划)
☆☆☆思路:动态规划 ——> 空间优化(使用一维数组而不是二维数组,这样只使用了O(n)的额外空间。)
class Solution { public int minimumTotal(List<List<Integer>> triangle) { /** * 方法1:DP 时间复杂度和空间复杂度 都是O(n^2) */ /* int m = triangle.size(); // 1. 状态的定义:dp[i][j]表示从点(i,j)到底边的最小路径和 int[][] dp = new int[m + 1][m + 1]; // 从三角形的最后一行开始递推。 for (int i = m - 1; i >= 0; i--) { for (int j = 0; j <= i; j++) { // 2. 状态转移方程 dp[i][j] = Math.min(dp[i+1][j], dp[i+1][j+1]) + triangle.get(i).get(j); } } return dp[0][0]; */ /** * 方法2:DP + 空间优化, 仅使用一维数组. 时间复杂度O(n^2),空间复杂度O(n) * 由于递推中,计算dp[i][j]时,只用到了下一行的dp[i+1][j]和dp[i+1][j+1]。 * 而不需要记录整个层的结果,因此dp数组不需要定义N行,只需要一行即可。 */ int m = triangle.size(); int[] dp = new int[m + 1]; for (int i = m-1; i >= 0; i--) { for (int j = 0; j <= i; j++) { dp[j] = Math.min(dp[j], dp[j+1]) + triangle.get(i).get(j); } } return dp[0]; } }