https://leetcode.com/problems/triangle/
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
For example, given the following triangle
[ [2], [3,4], [6,5,7], [4,1,8,3] ]The minimum path sum from top to bottom is
11
(i.e., 2 + 3 + 5 + 1 = 11).Note:
Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.
最直观的想法自然就是dfs然后和当前结果比较:
class Solution {
public:
int result = INT_MAX;
int row;
int minimumTotal(vector<vector<int>>& triangle) {
if(triangle.size() == 0) return 0;
row = triangle.size()-1;
dfs(triangle, 0, 0, triangle[0][0]);
return result;
}
void dfs(vector<vector<int>>& triangle, int r, int c, int cnt){
if(r == row){
if(cnt < result) result = cnt;
}else{
dfs(triangle, r+1, c, cnt+triangle[r+1][c]);
dfs(triangle, r+1, c+1, cnt+triangle[r+1][c+1]);
}
}
};
但是这个方法效率很低,一共有2^(triangle.size()-1)种可能的路径,在triangle规模很大的时候会直接TLE。
同时稍微想象一下就能发现在相邻两个结点向下一层移动的时候会有大量的重复计算,因此考虑使用dp
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
if(triangle.size() == 0) return 0;
vector<int> dp(triangle.size(), INT_MAX);
dp[0] = triangle[0][0];
for(int r = 1; r < triangle.size(); ++r){
for(int c = r; c > 0; --c){
dp[c] = min(dp[c], dp[c-1]) + triangle[r][c];
}
dp[0] += triangle[r][0];
}
int result = INT_MAX;
for(int i = 0; i < dp.size(); ++i){
if(dp[i] < result) result = dp[i];
}
return result;
}
};