力扣刷题笔记 120. 三角形最小路径和 C#

这篇博客介绍了如何使用动态规划解决力扣中的120题——三角形最小路径和。博主通过C#编程语言详细阐述了算法思路,包括自底向上求解、状态转移方程以及边界条件处理。最后提供了两种不同优化策略的代码实现,一种处理边界情况,另一种通过额外数组空间避免越界。
摘要由CSDN通过智能技术生成

今日签到题,题目如下:

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

相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。

 

例如,给定三角形:

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。来源:力扣(LeetCode)

说明:

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

链接:https://leetcode-cn.com/problems/triangle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

动态规划做多了真的是很容易联想到动态规划了。

自顶而下的最小路径和,也可以理解为自底而上的最小路径和。每个节点有两个子节点,只选择路径和最短的那个子节点移动。即每个节点的路径和状态转移自子节点的路径和。

假设父节点的下标为 i ,则其子节点下标为 i 和 i + 1,所以只需要建立一个长度为 n(n 为三角形的总行数)的 int 数组 dp 保存状态(因为更新 dp[i] 时,状态只转移自 dp[i] 和 dp[i+1],更新 dp[i-1] 不影响其状态)。

边界为最底层,先遍历最底层存入 dp。

右下至上从最下层第二行遍历整个三角形,根据上述状态转移规则,表达式为 dp[i] = dp[i] < dp[i+1]?dp[i]:dp[i+1]。完成状态转移后,还需要加上本格路径,表达式为 dp[i] += triangle[j][i]。最后收束到根节点即 dp[0] 为答案。

复杂度分析:

遍历了整个三角形,时间复杂度为 O(N^2)。

使用一个长度为 n 的额外数组,空间复杂度为 O(N)。

以下为自己提交的代码:

public class Solution {
    public int MinimumTotal(IList<IList<int>> triangle) {
        if (triangle.Count < 1)
        {
            return 0;
        }
        int[] dp = new int[triangle.Count];
        for (int i = triangle.Count - 1; i >= 0; i--)
        {
            dp[i] = triangle[triangle.Count - 1][i];
        }
        for (int i = triangle.Count - 2; i >= 0; i--)
        {
            for(int j = 0; j <= i; j++)
            {
                dp[j] = dp[j] < dp[j + 1] ? dp[j]:dp[j + 1];
                dp[j] += triangle[i][j];
            }
        }
        return dp[0];
    }
}

以上避免越界我先进行了一次判断和一次循环赋值。看完题解之后法线,只需要令 dp 多申请一位就可以优化写法。因为数组 dp 初始化每位都为 0,所以可以作为边界的状态转移。多申请一维避免边界的最后一位状态转移时越界。

复杂度同上。

以下为自己提交的代码:

public class Solution {
    public int MinimumTotal(IList<IList<int>> triangle) {
        int[] dp = new int[triangle.Count + 1];
        for (int i = triangle.Count - 1; i >= 0; i--)
        {
            for(int j = 0; j <= i; j++)
            {
                dp[j] = dp[j] < dp[j + 1] ? dp[j]:dp[j + 1];
                dp[j] += triangle[i][j];
            }
        }
        return dp[0];
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值