LeetCode120. Triangle(动态规划)
- Medium
 - Accepted:172,497
 - Submissions:447,076
 
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.
链接
https://leetcode.com/problems/triangle
题意
给定一个三角形,找出从顶到底的最小路径和,每一步只能移到下一行相邻(左下右下)的两个数字。
题解
对于一个数字,有往左下和右下两种走法。这样的话考虑一共n行,那么时间复杂度就是$O(2^n)$。
实际上这样做的话会产生很多重复计算,对于样例,第二层的3和4都可以选择5,所以5往下的就会被重复计算。
一个可行的办法是“记忆化搜索”,或者我们直接采用自底向上的动态规划。
从第n-1层开始,对该层进行循环然后计算该层的某个数加上第n层的某个数,即左下和右下取一个最小值,然后一层一层往上走,到达第一层后得到的就是结果。
假设$dp[i][j]$表示第i层第j个数到最底层路径的最小值,那么动态规划方程为:$dp[i][j] = min(dp[i+1][j], dp[i+1][j+1]) + dp[i][j]$。
[
     [2],          [11]
    [3,4],   -->  [9,10]
   [6,5,7],      [7,6,10]
  [4,1,8,3]   
]平均时间复杂度$O(n^2)$,如果直接在原数组上操作的话,空间复杂度$O(1)$。
代码
- Runtime: 8 ms, faster than 99.87% of C++ online submissions for Triangle.
 - Memory Usage: 9.9 MB, less than 94.41% of C++ online submissions for Triangle.
 
class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        int n = triangle.size();
        for (int i = n - 2; i >= 0; --i)
        {
            int m = triangle[i].size();
            for (int j = 0; j < m; ++j)
                triangle[i][j] += min(triangle[i+1][j], triangle[i+1][j+1]);
        }
        return triangle[0][0];
    }
};The end.
2019年3月23日 星期六