【LeetCode-Java实现】120.Triangle

120.Triangle

    • 题目描述
    • 思路
    • 实现代码

题目描述

Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
Example, given the following triangle
[
----- [2],
-----[3,4],
— [6,5,7],
—[4,1,8,3]
]
The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).
Note:
Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.

思路

(这种看起来可以暴力枚举,但是枚举时间复杂度很高的题一般可以使用动态规划来求解)
对于本题,很自然地会考虑是从上往下递推,还是从下往上递推,其实没差太多,我习惯动态规划从后往前递推,
所以假设最优解三角形 dp[i][j](存放从底层向上递推时,走到第i行第j列的最优解)
dp二维数组所有元素初始值为0,最底层就存放着原三角形triangle最底层的元素,
然后从倒数第二行开始从下往上递推,
[2]
[3,4]
[6,5,7]
程序识别出的三角形是上面的那种直角三角形,按题中要求,相邻只能是正下方和右下方
【LeetCode-Java实现】120.Triangle_第1张图片
想要递推出元素4那个位置的最优解,可能由5或者7推上去
5更小,所以选择5推到4
【LeetCode-Java实现】120.Triangle_第2张图片
原来的4就变成了5+4=9

归纳:
【LeetCode-Java实现】120.Triangle_第3张图片
即:dp[i][j]=min( dp[i+1] [j] , dp[i+1] [j+1] ) + triangle[i][j]
依次类推,直到推到最顶端,即为想要的最优解。

不过,本题没必要新建二维数组来作为递推容器,题目中给出的列表triangle就可以实现动态规划,思路基本一致,只是列表操作有所区别。

实现代码

直接将题中列表triangle作为递推容器的代码

public int minimumTotal(List<List<Integer>> triangle) {
		int row=triangle.size();  //三角形行数, 定义row简化代码书写
		if(row==0) return 0;      //异常情形
		
		//从倒数第二行开始,从下向上递推
		for(int i=row-2;i>=0;i--) {                     //行(从下向上)
			for(int j=0;j<triangle.get(i).size();j++){  //列(从左向右)
				    int min=Math.min(triangle.get(i+1).get(j),triangle.get(i+1).get(j+1));
				    triangle.get(i).set(j, min+triangle.get(i).get(j));   //核心:动态规划状态转移方程
			}
		}
		return triangle.get(0).get(0);
	}

你可能感兴趣的:(LeetCode,动态规划)