LeetCode 120. 三角形最小路径和(Triangle)

题目描述

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

例如,给定三角形:

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

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

说明:

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

解题思路

考虑用动态规划解题。用一个数组dp[n]记录每层各个节点为路径终点的最小路径和,这样每遍历到新的一层,就根据上一层记录的dp来更新本层的dp.由于以某节点为终点的路径的上一个节点可以是两个不同的节点,而更新dp会覆盖路径中的节点,所以用f来记录对应本节点在上一层靠左的最小路径,并且用l记录上一层最右端的最小路径。具体而言分为三种情况:

  • 若n=0,即遍历到本层的第一个节点,那么以此节点为终点的路径只有一条,直接更新dp[n]=dp[n]+triangle[i][j]
  • 若n=i,即遍历到本层的最后一个节点,那么以此节点为终点的路径只有一条,直接更新dp[n]=l+triangle[i][j]
  • 若0<n<i,即遍历到中间节点,首先记录最小路径和path=min(f+triangle[i][j],dp[j]+triangle[i][j]),然后更新f=dp[j],dp[j]=path

如果遍历到最后一层,那么用minSum记录该层的最小路径和,没计算出一个节点的最小路径和,就更新minSum

代码

 1 class Solution {
 2 public:
 3     int minimumTotal(vector<vector<int>>& triangle) {
 4         int n=triangle.size();
 5         if(n==1)
 6             return triangle[0][0];
 7         vector<int> dp(n,triangle[0][0]);
 8         int minSum=INT_MAX;
 9         int f,l;
10         for(int i=1;i<n;i++){
11             f=dp[0];
12             l=dp[i-1];
13             for(int j=0;j<=i;j++){
14                 if(j==0)
15                     dp[j]+=triangle[i][j];
16                 else if(j==i)
17                     dp[j]=l+triangle[i][j];
18                 else{
19                     int path=min(f+triangle[i][j],dp[j]+triangle[i][j]);
20                     f=dp[j];
21                     dp[j]=path;
22                 }
23                 if(i==n-1)
24                     if(dp[j]<minSum)
25                         minSum=dp[j];
26             }
27         }
28         return minSum;
29     }
30 };

猜你喜欢

转载自www.cnblogs.com/wmx24/p/9069873.html