算法-三角形最小路徑
1、三角形最小路徑(n^2空間複雜度)
120. 三角形最小路徑和 難度爲medium
給定一個三角形,找出自頂向下的最小路徑和。每一步只能移動到下一行中相鄰的結點上。
例如,給定三角形:
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
自頂向下的最小路徑和爲 11(即,2 + 3 + 5 + 1 = 11)。
說明:
如果你可以只使用 O(n) 的額外空間(n 爲三角形的總行數)來解決這個問題,那麼你的算法會很加分。
我們先來滿足基本需求,先求最小路徑
我們定義一個狀態變量,dp[i][j]表示從底部到這裏來最小值,將這個三角形視爲一個n*n的矩陣,用matrix[i][j]表示當前位置的值那麼我們有
dp[i][j]=matrix[i][j]+Math.min(dp[i+1][j],dp[i+1][j]);//下一行的值和下一行下個位置的值
對於最後一層,我們有
dp[i][j]=matrix[i][j];
自底向上動態規劃可以得到
public int minimumTotal(List<List<Integer>> triangle) {
int[][] dp=new int[triangle.size()][triangle.size()];
int layer=dp.length-1;
while(layer>=0){
List<Integer> list=triangle.get(layer);
for(int i=0;i<list.size();i++){
if(layer==dp.length-1){
dp[layer][i]=list.get(i);
}else{
dp[layer][i]=list.get(i)+Math.min(dp[layer+1][i],dp[layer+1][i+1]);
}
}
layer--;
}
return dp[0][0];
}
2、三角形最小路徑(n空間複雜度)
實際上,我們只需要記錄下一層的動態規劃值就行了,不需要全記錄,由於當前層是下一層的當前位置和下一層當前位置的下一個位置組成的,因此我們可以複用當前位置
public int minimumTotal(List<List<Integer>> triangle) {
int[] dp=new int[triangle.size()];
int layer=dp.length-1;
while(layer>=0){
List<Integer> list=triangle.get(layer);
for(int i=0;i<list.size();i++){
if(layer==dp.length-1){
dp[i]=list.get(i);
}else{
dp[i]=list.get(i)+Math.min(dp[i],dp[i+1]);//複用當前位置
}
}
layer--;
}
return dp[0];
}