120.Triangle:修订间差异
第1行: | 第1行: | ||
=Description= | =Description= | ||
{{LeetCode|id=triangle|no=120|title=Triangle | {{LeetCode | ||
|id=triangle | |||
Given a triangle array, return the minimum path sum from top to bottom. | |no=120 | ||
|difficulty=Medium | |||
|category=Dynamic Programming | |||
|collection=Top 150 | |||
|title=Triangle | |||
|summary=Given a triangle array, return the minimum path sum from top to bottom.}} | |||
For each step, you may move to an adjacent number of the row below. More formally, if you are on index i on the current row, you may move to either index i or index i + 1 on the next row. | For each step, you may move to an adjacent number of the row below. More formally, if you are on index i on the current row, you may move to either index i or index i + 1 on the next row. |
2023年9月23日 (六) 05:28的版本
Description
#120 | Triangle | Medium | ||
---|---|---|---|---|
Dynamic Programming | Top 150 | |||
Given a triangle array, return the minimum path sum from top to bottom. |
For each step, you may move to an adjacent number of the row below. More formally, if you are on index i on the current row, you may move to either index i or index i + 1 on the next row.
Example 1:
Input: triangle = [[2],[3,4],[6,5,7],[4,1,8,3]]
Output: 11
Explanation: The triangle looks like:
2
3 4
6 5 7
4 1 8 3
The minimum path sum from top to bottom is 2 + 3 + 5 + 1 = 11 (underlined above).
Example 2:
Input: triangle = [[-10]]
Output: -10
Solution
First attampt
It works, but not good, especially memory.
- Runtime 3 ms
- Beats 65.79%
- Memory 44.4 MB
- Beats 13.95%
class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
int maxRowSize = triangle.get(triangle.size() -1).size();
// create an array nxn to store the minimal distance that starts from triangle[i][j]
int[][] dp = new int[maxRowSize][maxRowSize];
for(int i = triangle.size() -1; i >=0; i--) {
List<Integer> row = triangle.get(i);
for(int j = 0; j < row.size(); j++) {
if(i < dp.length -1) {
// calculate minimal distance and update
dp[i][j] = Math.min(dp[i+1][j], dp[i+1][j+1]) + row.get(j);
} else {
// for the bottom line, there's no subpaths
dp[i][j] = row.get(j);
}
}
}
return dp[0][0];
}
}
Memory Optimization
class Solution {
public int minimumTotal(List<List<Integer>> triangle) {
int maxRowSize = triangle.get(triangle.size() -1).size();
// 只需要记录上一次的最短路径
int[] dp = new int[maxRowSize];
for(int i = triangle.size() -1; i >=0; i--) {
List<Integer> row = triangle.get(i);
for(int j = 0; j < row.size(); j++) {
if(i < dp.length -1) {
// 从左到右更新,正好计算右边的元素时,当前的值已经不需要用到了。所以可以直接更新
dp[j] = Math.min(dp[j], dp[j+1]) + row.get(j);
} else {
dp[j] = row.get(j);
}
}
}
return dp[0];
}
}