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.
Hide Tags Array Dynamic Programming
分析:
動態規劃,重點就是找遞推公式。。。
只需要從上到下,從左到右,計算出每個元素的最小路徑和,然後再找出最後一行中的最小值即可。
由於題目要求只用O(n)空間複雜度,那麼可以直接修改原二維數組,每遍歷一個元素,將其更新爲最小路徑和即可,最後一行的時候,同時更新最終的最小路徑和。
需要注意的地方,每一行的首元素和末尾元素只有一個相鄰的元素,需分開處理。
對於第[i][j]個元素(第i行第j列元素,i > 0):
若是行首元素,那麼tri[i][j] += tri[i-1][j]
若是行尾元素,那麼tri[i][j] += tri[i-1][j-1]
若是中間元素,那麼 tri[i][j] += min(tri[i-1][j-1],tri[i-1][j])
此時若是最後一行,在更新每個元素對應的最小路徑和之後,更新全局的最小路徑和minSum。(也可以在所有計算完成之後,再去找最後一行的最小值,效率一樣)
以下是C++實現代碼:
/*/////////////////8ms//*/
class Solution {
public:
int min(int a, int b){
return a < b? a:b;
}
int minimumTotal(vector<vector<int> > &tri) {
int n = tri.size();
if(n == 0) // 若數組爲空,則返回0
return 0;
if(n == 1) // 只有一行,那麼只有一個元素,返回即可
return tri[0][0];
int minSum = INT_MAX; //全局最小路徑和
for(int i = 1; i < n; i++){ //從第1行開始,計算每個元素對應的最小路徑和,並更新到本身的位置
int m = tri[i].size(); //程序執行到此處,表示m必然大於0
for(int j = 0; j < m; j++){ //處理第i行的所有元素
if(j == 0) //更新行首元素的最小路徑和
tri[i][j] += tri[i-1][j];
else if(j == m-1) //更新行尾元素的最小路徑和
tri[i][j] += tri[i-1][j-1];
else{ //非行首尾的元素則利用遞推公式進行計算
tri[i][j] += min(tri[i-1][j-1],tri[i-1][j]);
}
if(i == n-1){ // 利用最後一行的最小路徑和更新minSum
if(tri[i][j] < minSum)
minSum = tri[i][j];
}
}
}
return minSum;
}
};