Leetcode 120. 三角形最小路徑和 C++
阿新 • • 發佈:2019-02-02
題目描述:
給定一個三角形,找出自頂向下的最小路徑和。每一步只能移動到下一行中相鄰的結點上。
例如,給定三角形:
[ [2], [3,4], [6,5,7], [4,1,8,3] ]
自頂向下的最小路徑和為 11
(即,2 + 3 + 5 + 1 = 11)。
說明:
如果你可以只使用 O(n) 的額外空間(n 為三角形的總行數)來解決這個問題,那麼你的演算法會很加分。
解答:
方法一:
空間複雜度O(),但是在leetcode上執行時間只有了4ms,戰勝了99.92%的cpp提交者。我自己不是太懂為什麼方法一比方法二會快這麼多,因為迴圈都一樣的歷遍了元素,而且方法一還多了一個尋找最小值的迴圈。
方法一的思路是典型的動態規劃求法,是很容易想到的。用一個矩陣info來儲存到每一個點的最小值,分三種情況,
(1)如果元素在開頭,那麼 等於當前值加上它上一行對應的最小值。info[i][j]=triangle[i][j]+info[i-1][j]
(2)如果元素位於末尾,那麼等於當前值加上它上一行的最後一個元素。
(3)如果是在中間,那麼就要找上一行中能到達它的最小元素。
class Solution { public: int minimumTotal(vector<vector<int>>& triangle) { int n=triangle.size(); if(n==0) return 0; if(n==1) return triangle[0][0]; vector<vector<int>> info(n,vector<int>(n,0)); info[0][0]=triangle[0][0]; for(int i=1;i<n;++i) { for(int j=0;j<=i;++j) { if(j==0) info[i][j]=triangle[i][j]+info[i-1][j]; else if(j==i) info[i][j]=triangle[i][j]+info[i-1][j-1]; else { int temp=info[i-1][j]>info[i-1][j-1]?info[i-1][j-1]:info[i-1][j]; info[i][j]=temp+triangle[i][j]; } } } int res=info[n-1][0]; for(int i=0;i<n;++i) { if(info[n-1][i]<res) { res=info[n-1][i]; } } return res; } };
方法二:
空間複雜度O(n),執行用時52ms,比較慢。
這種方法從最下面開始,向上尋找答案。只用一個長度為n的數列就可以儲存全部資訊。自下而上,計算完該層的最小值後,資訊不斷地在這個數列中更新,所以可以節省空間。
class Solution { public: int minimumTotal(vector<vector<int>>& triangle) { int n=triangle.size(); if(n==0) return 0; vector<int> info(n,0); for(int i=n-1;i>=0;--i) { for(int j=0;j<=i;++j) { if(i==n-1) info[j]=triangle[i][j]; else { int temp=(info[j]>info[j+1])?info[j+1]:info[j]; info[j]=triangle[i][j]+temp; } } } return info[0]; } };
參考: