LeetCode--120:三角形最小路径和(java)

原题链接
方法1:暴力递归(超时)

class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
		if(triangle == null || triangle.size() == 0) return 0;
		return helper(triangle, 0, 0);//需要处理的层和索引
	}
	private int helper(List<List<Integer>> triangle, int level, int index) {
		if(level == triangle.size() - 1) return triangle.get(level).get(index);
		int left = helper(triangle, level + 1,index);
		int right = helper(triangle, level + 1,index + 1);
		return triangle.get(level).get(index) + Math.min(left, right);
	}
}

方法2:动态规划(自底向上)
二维数组 dp(i, j)表示 i 行 j 列元素到三角形底层的最小路径和。
DP方程:dp(i, j)= min( dp ( i+1, j),dp ( i+1, j+1)) + triangle(i, j)。
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
例如,4的最小路径和就等于 5 和 7 的最小路径和的较小者 + 4。显然 dp 数组最后一行的值,就是 triangle 最后一行的值。

	public int minimumTotal(List<List<Integer>> triangle) {
		if(triangle == null || triangle.size() == 0) return 0;
		int lastRowSize = triangle.get(triangle.size() - 1).size();
		int row = triangle.size();//行数
		int[][] dp = new int[row][lastRowSize];//最大行,最大列
		//初始化dp,最后一行的dp值就是triangle最后一行的值
		for(int i = 0;i < lastRowSize;i++) {
			dp[dp.length - 1][i] = triangle.get(row - 1).get(i);
		}
		for(int i = dp.length - 2; i >= 0; i--) {//从倒数第二行往上递推
			for(int j = 0;j < i + 1;j++) {//第 i 行有 i + 1个元素
				dp[i][j] = Math.min(dp[i + 1][j], dp[i + 1][j + 1]) + triangle.get(i).get(j);
			}
		}
		return dp[0][0];
	}

因为递推 第 i 行的 dp 值时,我们只需要第 i + 1 行的 dp 值,所以还可以优化为一维 dp

	public int minimumTotal(List<List<Integer>> triangle) {
		int row = triangle.size();//triangle有几行,单行最多就有几个元素
        int[] dp = new int[row];
        for (int i = 0; i < row; i++) dp[i] = triangle.get(row - 1).get(i); //初始化triangle的最后一行数组
        for (int i = row - 2; i >= 0; i--)  //从倒数第二行数组开始
            for (int j = 0; j < i + 1; j++)
            	//在执行重写操作之前,dp[j]其实就是dp[i+1][j]
                dp[j] = Math.min(dp[j], dp[j + 1]) + triangle.get(i).get(j);
        return dp[0];
    }
发布了24 篇原创文章 · 获赞 3 · 访问量 545

猜你喜欢

转载自blog.csdn.net/QinLaoDeMaChu/article/details/104003875
今日推荐