タイトル説明
三角形を考えると、最小値とトップダウンパスを見つけます。各ステップは、次の行の隣接ノードへ移動することができます。
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。请使用O(n)的空间。
問題解決のためのアイデア
この質問は、実際には、あなたが使用することができ、アイデアを投獄することがない、難しいことではありません 余分なスペースの問題解決。
- トップダウン:私たちは、元の使用することができ
vector<vector<int>>& triangle
、それ自体が格納されている状態、ケースのスペースの複雑さを 。 - ボトムアップ:時々 、より簡単である問題の方向を変更し、あなたが境界条件の多様性を考慮することはできません。(私は実現します)
参照コード
私は(トップダウン)を実現します
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
int rows = triangle.size();
for(int i = 1; i < rows; i++){
for(int j = 0; j <= i; j++){
int left = j-1 >= 0? triangle[i-1][j-1]: INT_MAX;
int right = j <= i-1? triangle[i-1][j]: INT_MAX;
triangle[i][j] = min(left, right) + triangle[i][j];
}
}
int res = INT_MAX;
for(int i = 0; i < rows; i++)
res = min(res, triangle[rows-1][i]);
return res;
}
};
兄が実装(ボトムアップ)
class Solution {
public:
//题解1:动态规划,自底向上,从倒数第二层开始向上求解(不用边界处理)
//状态转移方程为:triangle[i][j]+=min(triangle[i+1][j],triangle[i+1][j+1])
//时间复杂度为O(m*n),空间复杂度为O(1)
int minimumTotal_1(vector<vector<int>>& triangle) {
for(int i=triangle.size()-2;i>=0;--i){
for(int j=0;j<triangle[i].size();++j){//每个点的路径和等于该点的值加上它正下面和右下中较小点的值
triangle[i][j]+=min(triangle[i+1][j],triangle[i+1][j+1]);
}
}
return triangle[0][0];
}
//题解2:降维变为一维dp,自底向上,因为其实每次只会用到上一层数据,因此不需二维数组存储所有可能情况来进行比较
//也就是说一维dp[j]是随着i进行覆盖更新上一层的dp[j]
int minimumTotal(vector<vector<int>>& triangle){
int n=triangle.size(),dp[n+1];
memset(dp,0,sizeof(dp));
for(int i=n-1;i>=0;--i){
for(int j=0;j<=i;++j){//第i层只有i列
dp[j]=min(dp[j],dp[j+1])+triangle[i][j];
}
}
return dp[0];
}
};