【Leetcode】120.三角形最小路径和

一、题目

1、题目描述

给定一个三角形 triangle ,找出自顶向下的最小路径和。

每一步只能移动到下一行中相邻的结点上。相邻的结点 在这里指的是 下标上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。也就是说,如果正位于当前行的下标 i ,那么下一步可以移动到下一行的下标 ii + 1

示例1:

复制代码
输入:triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
输出:11
解释:如下面简图所示:
   2
  3 4
 6 5 7
4 1 8 3
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

示例2:

复制代码
输入:triangle = [[-10]]
输出:-10

提示:

  • 1 <= triangle.length <= 200
  • triangle[0].length == 1
  • triangle[i].length == triangle[i - 1].length + 1
  • -104 <= triangle[i][j] <= 104

进阶:

  • 你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题吗?

2、基础框架

cpp 复制代码
class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {

    }
};

3、原题链接

120.三角形最小路径和

二、解题报告

1、思路分析

动态规划 + 空间优化

动态规划的经典题目,堪称入门题。

(i,j) 位置看成一个状态,定义 dp[i][j] 表示 从 (i,j) 位置出发得到的最小路径和。在(i,j) 位置有两种决策:向左下走到 (i+1,j) 位置,后续从 (i+1,j) 位置出发得到最小路径和;同理,向右下走到(i+1,j+1) 位置,后续从 (i+1,j+1) 位置出发得到最小路径和。

所以可以得到转移方程:
d p [ i ] [ j ] = t r i a n g l e [ i ] [ j ] + m i n ( d p [ i + 1 ] [ j ] , d p [ i + 1 ] [ j + 1 ] ) dp[i][j] = triangle[i][j] + min(dp[i+1][j], dp[i+1][j+1]) dp[i][j]=triangle[i][j]+min(dp[i+1][j],dp[i+1][j+1])

也就是说,(i,j) 位置的状态依赖于 (i+1,j)(i+1, j+1) 位置的状态,于是逆序枚举 i。见代码详解中的"动态规划"写法。

(i,j) 位置的状态只依赖于 (i+1,j)(i+1, j+1) 位置的状态,所以用一维数组即可。代码见"动态规划 + 空间优化"写法。

2、时间复杂度

O ( N 2 ) O(N^2) O(N2)

3、代码详解

  • 动态规划
cpp 复制代码
class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        int n = triangle.size();

        int dp[n][n];
        memset(dp, 0, sizeof(dp));

        for (int j = 0; j < n; j++) {
            dp[n - 1][j] = triangle[n - 1][j]; //最后一行的状态
        }

        for (int i = n - 2; i >= 0; i--) { //逆序枚举
            for (int j = 0; j <= i; j++) {
                dp[i][j] = triangle[i][j] + min(dp[i + 1][j], dp[i+1][j+1]);
            }
        }

        return dp[0][0];
    }
};
  • 动态规划 + 空间优化
cpp 复制代码
class Solution {
public:
    int minimumTotal(vector<vector<int>>& triangle) {
        int n = triangle.size();

        int dp[n];
        memset(dp, 0, sizeof(dp));

        for (int j = 0; j < n; j++) {
            dp[j] = triangle[n - 1][j]; //最后一行的状态
        }

        for (int i = n - 2; i >= 0; i--) { //逆序枚举
            for (int j = 0; j <= i; j++) {
                dp[j] = triangle[i][j] + min(dp[j], dp[j+1]);
            }
        }

        return dp[0];
    }
};
相关推荐
一起养小猫2 小时前
LeetCode100天Day14-轮转数组与买卖股票最佳时机
算法·leetcode·职场和发展
程序员-King.4 小时前
day143—递归—对称二叉树(LeetCode-101)
数据结构·算法·leetcode·二叉树·递归
Ethan-D6 小时前
#每日一题19 回溯 + 全排列思想
java·开发语言·python·算法·leetcode
橘颂TA7 小时前
【剑斩OFFER】算法的暴力美学——LeetCode 733 题:图像渲染
算法·leetcode·职场和发展
FMRbpm9 小时前
树的练习6--------938.二叉搜索树的范围和
数据结构·c++·算法·leetcode·职场和发展·新手入门
多米Domi0119 小时前
0x3f 第35天 电脑硬盘坏了 +二叉树直径,将有序数组转换为二叉搜索树
java·数据结构·python·算法·leetcode·链表
想逃离铁厂的老铁9 小时前
Day45 >> 115、不同的子序列 + 583. 两个字符串的删除操作 + 72. 编辑距离
算法·leetcode
程序员-King.10 小时前
day144—递归—平衡二叉树(LeetCode-110)
算法·leetcode·二叉树·递归
老鼠只爱大米10 小时前
LeetCode经典算法面试题 #739:每日温度(单调栈、动态规划等多种实现方案详解)
算法·leetcode·面试·动态规划·单调栈·每日温度
老鼠只爱大米10 小时前
LeetCode经典算法面试题 #394:字符串解码(递归、双栈、迭代构建等五种实现方案详解)
算法·leetcode·面试·递归··字符串解码