题目:
给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。
相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。
例如,给定三角形:
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。
说明:
如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/triangle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:这个题比较简单,典型的动态规划问题。实现的时候,我从底部开始向上dp。当然从上到下也可。
在状态转移的时候,可以重复使用一个一维状态数组dp,因为上次的状态在这次使用过后就没有用处了,所以直接在原状态dp[i]处即可更新为新的dp[i]。因为:只能移动到下一行相邻的点。
即:dp[i] = min(dp[i]+ob[i], dp[i+1]+ob[i])。
将给出的三角形转化为一个n*n矩阵很好理解该方程。
其中,左边的dp[i]表此处的状态,现在还没有更新。
右边的dp[i]事实上指的是当前层的下一层的第i个位置处的状态。同理,dp[i+1]指的是当前层的下一层的第i+1个位置处的状态。
因为当你处在一个位置时,要么向下走,要么向斜右下方走。这两个方向分别对应等式右边的两个dp:dp[i]与dp[i+1]。
比如,当处于值为5的位置时,其状态只能有下面的值为1或者值为8的位置处的状态转变而来。
实现:
JAVA版:
package leetcode;
import java.util.ArrayList;
import java.util.List;
/*
USER:LQY
DATE:2020/7/14
TIME:9:37
*/
public class leetcode_120 {
public static void main(String []args){
List<Integer> inner1 = new ArrayList<>();
List<Integer>inner2 = new ArrayList<>();
List<Integer>inner3 = new ArrayList<>();
List<Integer>inner4 = new ArrayList<>();
List<List<Integer>> outer = new ArrayList<>();
inner1.add(2);
inner2.add(3);inner2.add(4);
inner3.add(6);inner3.add(5);inner3.add(7);
inner4.add(4);inner4.add(1);inner4.add(8);inner4.add(3);
outer.add(inner1);
outer.add(inner2);
outer.add(inner3);
outer.add(inner4);
new leetcode_120().minimumTotal(outer);
}
public int minimumTotal(List<List<Integer>> triangle) {
// int ans = 0;
int len = triangle.size();
int []dp = new int[len];
List<Integer> temp = triangle.remove((len-1));
int index = 0;
for(int i: temp){
dp[index++] = i;
}
for(int i = 0;i < len;i++)
System.out.print(dp[i]+" ");
System.out.println();
int size = len - 1;
while(size > 0){
temp = triangle.remove(size-1);
index = 0;
for(int i : temp){
dp[index] = Math.min(i+dp[index], i+dp[index+1]);
index++;
}
for(int i = 0;i < size;i++)
System.out.print(dp[i]+" ");
System.out.println();
size--;
}
return dp[0];
}
}
Python版:
class Solution:
def minimumTotal(self, triangle: List[List[int]]) -> int:
lens = len(triangle)
dp = triangle[lens-1][:]
size = lens - 1
while(size > 0):
index = 0
for i in triangle[size-1][:]:
dp[index] = min(i+dp[index], i+dp[index+1])
index += 1
size -= 1
return dp[0]