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

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]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值