题目描述
给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。相邻的结点,在这里指的是下标与上一层结点下标相同或者等于上一层结点下标 + 1 的两个结点。
例如,给定三角形:
1 | [ |
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
递归
给定的三角形的行数为 n,并且第 i 行(从 0 开始编号)包含了 i + 1
个数。如果将每一行的左端对齐,那么会形成一个等腰直角三角形,如下所示:
1 | [2], |
这样,我们可以从顶点自上而下递归处理最小路径和,首先从顶点开始,他的最小路径和是顶点的数2加上下面的以3为顶点的最短路径和,或者顶点2加上下面以4为顶点的最短路径和,取其中的最小值,并不断递归处理。这里需要注意的一点是,对于第二行的顶点3和4,计算他们下一层的最短路径和的时候,会计算两遍第三行的以5为顶点的三角形最短路径和。所以我们在递归的同时,记录下计算过的路径和,防止重复计算。
1 | public int minimumTotal(List<List<Integer>> triangle) { |
复杂度分析
- 时间复杂度:O(n²),其中 n 是三角形的行数。
- 空间复杂度:O(n²),我们需要一个 n ∗ n 的二维数组存放记录的值。
动态规划-自顶向下
我们用 f[i][j]
表示从三角形顶部走到位置 (i, j)
的最小路径和。这里的位置 (i, j)
指的是三角形中第 i 行第 j 列(均从 0 开始编号)的位置。由于每一步只能移动到下一行「相邻的节点」上,因此要想走到位置 (i, j)
,上一步就只能在位置 (i - 1, j - 1)
或者位置 (i - 1, j)
。我们在这两个位置中选择一个路径和较小的来进行转移,状态转移方程为:
f[i][j] = min(f[i − 1][j − 1], f[i − 1][j]) + c[i][j]
其中 c[i][j]
表示位置 (i, j)
对应的元素值。
注意第 i 行有 i + 1
个元素,它们对应的 j 的范围为 [0, i]
。当 j = 0
或 j = i
时,上述状态转移方程中有一些项是没有意义的。例如当 j = 0
时,f[i − 1][j − 1]
没有意义,因此状态转移方程为:
f[i][0] = f[i − 1][0] + c[i][0]
即当我们在第 i 行的最左侧时,我们只能从第 i − 1
行的最左侧移动过来。当 j = i
时,f[i - 1][j]
没有意义,因此状态转移方程为:
f[i][i] = f[i − 1][i − 1] + c[i][i]
即当我们在第 i 行的最右侧时,我们只能从第 i − 1
行的最右侧移动过来。
最终的答案即为 f[n − 1][0]
到 f[n − 1][n − 1]
中的最小值,其中 n 是三角形的行数。
边界条件为:
f[0][0] = c[0][0]
即在三角形的顶部时,最小路径和就等于对应位置的元素值。这样一来,我们从 1 开始递增地枚举 i,并在 [0, i]
的范围内递增地枚举 j,就可以完成所有状态的计算。
1 | public int minimumTotal(List<List<Integer>> triangle) { |
复杂度分析
- 时间复杂度:O(n²),其中 n 是三角形的行数。
- 空间复杂度:O(n²),我们需要一个 n ∗ n 的二维数组存放所有的状态。
动态规划-自底向上
跟上述的方法一致,只不过我们采用自底向上的方法,状态转移方程为:
dp[i][j] = min(dp[i + 1][j], dp[i + 1][j + 1]) + c[i][j]
1 | public int minimumTotal(List<List<Integer>> triangle) { |
复杂度分析
- 时间复杂度:O(n²),其中 n 是三角形的行数。
- 空间复杂度:O(n²),我们需要一个 n ∗ n 的二维数组存放所有的状态。
动态规划-空间优化
在上述代码中,我们定义了一个 N 行 N 列 的 dp 数组(N 是三角形的行数)。但是在实际递推中我们发现,计算 dp[i][j]
时,只用到了下一行的 dp[i + 1][j]
和 dp[i + 1][j + 1]
。因此 dp 数组不需要定义 N 行,只要定义 1 行就行。所以我们稍微修改一下上述代码,将 i 所在的维度去掉(如下),就可以将 O(N²) 的空间复杂度优化成 O(N)。
1 | public int minimumTotal(List<List<Integer>> triangle) { |
复杂度分析
- 时间复杂度:O(n²),其中 n 是三角形的行数。
- 空间复杂度:O(n),我们需要一个 n 的一维数组存放所有的状态。
来源
文章标题:三角形最小路径和
文章作者:cylong
文章链接:https://0skyu.cn/posts/4f4.html
有问题或者建议欢迎在下方评论。欢迎转载、引用,但希望标明出处,感激不尽(●’◡’●)
- 本文标题:三角形最小路径和
- 创建时间:2020-07-14 00:19:12
- 本文链接:posts/4f4.html
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!