leetcode 120. 三角形最小路径和

给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。

例如,给定三角形:

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]

自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

说明:

如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。

 dp1[i] 表示到达上一行第i个位置需要的最少路径和, dp[i]表示到达当前行第i个位置需要走的最小路径和; 到达第 i 行第 j 列只能通过第 i-1 行的 j-1 列或者 j 列到达, 

所以可以得到关系式dp[j] = min(dp[j-1], dp[j]) + triangle[i][j]; 边界条件是每一行的最左边和最右边; 该方法的额外空间是O(n)

 1 #include<algorithm>
 2 class Solution {
 3 public:
 4     int minimumTotal(vector<vector<int>>& triangle) {
 5         int n=triangle.size(), i, j;
 6         vector<int> dp(n, 0), dp1(n, 0);
 7         dp1[0]=dp[0]=triangle[0][0];
 8         for(i=1; i<n; i++){
 9             for(j=0; j<triangle[i].size(); j++){
10                 if(j==0) dp[j] = dp1[j] + triangle[i][j];
11                 else if(j==triangle[i].size()-1) dp[j] = dp1[j-1] + triangle[i][j];
12                 else dp[j] = min(dp1[j-1], dp1[j]) + triangle[i][j];
13             }
14             swap(dp1, dp);
15         }
16         sort(dp1.begin(), dp1.end());
17         return dp1[0];
18     }
19 };

每一行从右到左遍历,可以减少数组复制的过程; 

#include<algorithm>
class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        int n = triangle.size(), i, j;
        vector<int>dp(n);
        dp[0] = triangle[0][0];
        for(int i = 1; i < n; i++){
            dp[i] = dp[i - 1] + triangle[i][i];
            for(int j = i - 1; j > 0; j--)
                dp[j] = triangle[i][j] + min(dp[j], dp[j - 1]);
            dp[0] = dp[0] + triangle[i][0];
        }
        sort(dp.begin(), dp.end());
        return dp[0];
    }
};

猜你喜欢

转载自www.cnblogs.com/mr-stn/p/9212934.html