LeetCode -- Triangle 路徑求最小和( 動態規劃問題)

https://oj.leetcode.com/problems/triangle/

Triangle

 
Total Accepted: 10560 Total Submissions: 39313My Submissions

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.

Have you been asked this question in an interview? 

解題思路

這個題屬於動態規劃問題,解題思路如下:
法一:從上到下, 下一行的結果根據上一行的路徑累計和而計算。
triangle[i][j] += min(triangle[i-1[j-1],triangle[i-1][j]),這樣需要處理j=0和j=最大值。
法二:從下往上,每一行的結果根據下面一行的路基累計和而計算。(參考大神才曉得)
triangle[i][j] += min(triangle[i + 1][j], triangle[i + 1][j + 1])

對於此題子在面試的時候,除了題意,還要要問清楚這些題的其他問題,比如:傳遞的數據元素可以修改否? 最後求出的和sum會不會超出integer的範圍?


備註:這個題只需要輸出Triangle中最小路徑的和,並沒有要求輸出具體的路徑。若要求輸出路徑可以考慮添加相應的“指針”,基礎每個“點”的下/上上一個“點”的位置(小心:有多條最佳路徑)。我看好些關於動態規劃的OJ題都沒有要求給出具體路徑,其實這只是個求解過程的記錄問題。


下面依次爲參考源代碼:法一採用JAVA(採用不修改原數組元素),法二採用C++(修改原數組元素值)。

public int minimumTotal(List<List<Integer>> triangle) {
		//We record each minimum sum value for each index in the triangle.
		//We compute these values from top to bottom.
		List<List<Integer>> ixSum = new ArrayList<>(triangle.size()); 
		for (int i = 0; i < triangle.size(); ++i) {
			List<Integer> lines = triangle.get(i);
			ixSum.add(new ArrayList<Integer>(lines.size()));
			if (i == 0) {
				ixSum.get(0).add(lines.get(0)); //Notice that, we use 'add' method rather than 'set' method.
			} else {
				for (int j = 0; j < lines.size(); ++j) {
					if (j == 0) {
						ixSum.get(i).add((ixSum.get(i - 1).get(0) + lines.get(0)));
					} else if (j == (lines.size() - 1)) {
						// Notice that: ixSum.get(i).get(j-1).
						ixSum.get(i).add((ixSum.get(i - 1).get(j - 1) + lines.get(j)));
					} else {
						if (ixSum.get(i - 1).get(j) > ixSum.get(i - 1).get(j - 1)) {
							ixSum.get(i).add(ixSum.get(i - 1).get(j - 1) + lines.get(j));
						} else {
							ixSum.get(i).add(ixSum.get(i - 1).get(j) + lines.get(j));
						}
					}
				}
			}
		}
		int min = Integer.MAX_VALUE;
		for (int e : ixSum.get(ixSum.size()-1)) {
			if (e < min) {
				min = e;
			}
		}
		ixSum = null;
		return min;
	}

法二: C++代碼(修改原數組元素):

class Solution {
public:
    int minimumTotal(vector<vector<int> > &triangle) {
        for (int i = triangle.size() - 2; i >= 0; --i)
            for (int j = 0; j < i + 1; ++j){
                if(triangle[i+1][j] > triangle[i+1][j+1]){
                    triangle[i][j] += triangle[i+1][j+1];
                }else{
                    triangle[i][j] += triangle[i+1][j];
                }
            }
        
        return triangle[0][0];
    }
};


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章