1. 程式人生 > >【LeetCode】Triangle做題筆記

【LeetCode】Triangle做題筆記

題意:給出一個三角形,求出從頂到底的最小路徑和,路徑中每個節點必須是相鄰的。描述起來比較費勁,見題目中的示例如下:

例如,給出下面這個三角形
[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]
從頂到底的最小路徑和為11 (路徑為 2 + 3 + 5 + 1 = 11).

分析:剛開始拿到題目,想到的是貪心演算法,一路向下走,但是這種方法只能是區域性最小的,而不是全域性最小的。於是又想到了從下向上走,但是無論方向如何,一條路線上求出來的和一定是區域性最小,而不是全域性的。

所以怎樣求得全域性最小和,成了一個關鍵的問題,可以想象,最終的結果一定是從第一行到最後一行,例如示例中的結果路徑有2->4、2->1、2->8、2->3。找到這四條路徑裡每一條的最小和很簡單(就是貪心演算法所求得的區域性和),則全域性的最小和一定是這四條最小和裡最小的那個,因此我們只需要分配一個N個元素的陣列,用來儲存這N個區域性最小和即可。這樣也達到了Note中提到的使用O(n)的額外空間。

我選用的遍歷方式為從下向上,公式為:

f[j]=f[j]<f[j+1]?f[j]:f[+1];
f[j]+=triangle[i][j]
其中,i表示當前的行數,j表示當前的列數。

於是得到如下的程式碼:

class Solution {
public:
    int minimumTotal(vector<vector<int> > &triangle) {
        // Start typing your C/C++ solution below
        // DO NOT write int main() function
		vector<int> f(triangle.size());
		std::copy(triangle[triangle.size()-1].begin(), triangle[triangle.size()-1].end(), f.begin());
		for (int i = triangle.size()-2; i >= 0; --i)
		{
			for (int j = 0; j < triangle[i].size(); j ++)
			{
				f[j] = (f[j] < f[j+1] ?	f[j] : f[j+1]) + triangle[i][j];	
			}			
		}
		return f[0];   
    }
};