LeetCode-120:Triangle (三角形列表的最小路径和) -- medium

来源:互联网 发布:巡店软件 编辑:程序博客网 时间:2024/06/05 19:50

Question

Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.

For 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.

问题解析:

给定三角形二维列表,求出从顶到底的和最小的路径,每步只能在下一行的相邻两元素中选取。

Answer

Solution 1:

DP。

  • 由题目可以看出,其中每一步均由上一步的问题构成,所以利用动态规划来求解。
  • 由题目条件限定,要求只能在相邻元素中选取,观察可知,如本行取j,则下一行在jj+1中选取;
  • 构建动态规划数组,保存前一行和当前行符合题目要求的路径和,以自底向上的方式,最终归一到第0行的0元素位置。那么动态规划数组的第0个元素即为最小路径和。
class Solution {    public int minimumTotal(List<List<Integer>> triangle) {        int[] res = new int[triangle.size()+1];        for (int i = triangle.size()-1; i >= 0; i--){            for (int j = 0; j < triangle.get(i).size(); j++){                res[j] = Math.min(res[j], res[j+1]) + triangle.get(i).get(j);            }        }        return res[0];    }}
  • 时间复杂度:O(n^2),空间复杂度:O(n)

Solution 2:

Solution 1 的空间复杂度优化。

  • 通过观察可以知道,因为最终的和保存在动态规划数组的首位,我们可以直接将选取出的路径和加到triangle的前一行中,故无需构建新的动态规划数组。
  • 但由于需要修改triangle列表,需要set操作,相比解法一,减少了空间复杂度,却增加了时间复杂度;
class Solution {    public int minimumTotal(List<List<Integer>> triangle) {        for (int i = triangle.size()-2; i >= 0; i--){            for (int j = 0; j < triangle.get(i).size(); j++){                triangle.get(i).set(j, triangle.get(i).get(j) + Math.min(triangle.get(i + 1).get(j), triangle.get(i + 1).get(j + 1)));            }        }        return triangle.get(0).get(0);    }}
  • 时间复杂度:O(n^2) * O(set()),空间复杂度:O(1)

Solution 3:

python 解法,DP,与解法一相同。

为了加强对Python的练习,以后的练习中都会Python的程序。

class Solution:    def minimumTotal(self, triangle):        """        :type triangle: List[List[int]]        :rtype: int        """        if not triangle:            return        res = triangle[-1]        for i in range(len(triangle)-2, -1, -1):            for j in range(len(triangle[i])):                res[j] = min(res[j], res[j+1]) + triangle[i][j]        return res[0]