LeetCode - Triangle 路径求最小和( 动态规划有关问题)

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];
    }
};