题目
题目链接
解题思路:
- 这是一个动态规划问题
- 可以从底向上或从上向下进行动态规划
- 我们选择从底向上,因为这样更容易处理边界情况
- 从三角形的最后一行开始,向上遍历
- 对于每一行的每个位置 \(j\),\(dp_{i,j}\) 表示从该位置到底部的最小路径和
- 状态转移时,当前位置的最小路径和等于下一行相邻两个位置的最小值加上当前位置的值
- 最终 \(dp[0][0]\) 就是从顶点到底部的最小路径和
- 状态转移方程:\(dp[i][j] = min(dp[i+1][j], dp[i+1][j+1]) + triangle[i][j]\)
- 由于每行的状态只和下一行有关,所以可以使用一维数组优化空间。
代码
class Solution {
public:
    int minTrace(vector<vector<int> >& triangle) {
        int n = triangle.size();
        vector<int> dp(n + 1, 0);  // 使用一维dp数组优化空间
        
        // 从底向上
        for(int i = n-1; i >= 0; i--) {
            for(int j = 0; j <= i; j++) {
                dp[j] = min(dp[j], dp[j+1]) + triangle[i][j];
            }
        }
        
        return dp[0];
    }
};
import java.util.*;
public class Solution {
    public int minTrace(int[][] triangle) {
        if (triangle == null || triangle.length == 0) {
            return 0;
        }
        int n = triangle.length;
        int[] dp = new int[n + 1];
        
        // 从底向上
        for (int i = n-1; i >= 0; i--) {
            for (int j = 0; j <= i; j++) {
                dp[j] = Math.min(dp[j], dp[j+1]) + triangle[i][j];
            }
        }
        
        return dp[0];
    }
}
class Solution:
    def minTrace(self, triangle: List[List[int]]) -> int:
        n = len(triangle)
        dp = [0] * (n + 1)
        
        # 从底向上
        for i in range(n-1, -1, -1):
            for j in range(i + 1):
                dp[j] = min(dp[j], dp[j+1]) + triangle[i][j]
                
        return dp[0]
算法及复杂度分析
- 算法:动态规划
- 时间复杂度:\(\mathcal{O}(n^2)\),其中 \(n\) 是三角形的行数
- 空间复杂度:\(\mathcal{O}(n)\),使用一维dp数组