120. Trangle

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.

解析:

题目要求从上到下找到一条累加和最小的路径,每个节点只能达到相邻的下一层节点(例如第i 行中的第j个节点,只能到达第i+1行中的第j个和j+1个节点)。
比较暴力简单的解法是从上到下计算每一个可能的情况,这种暴力的解法是不提倡的。考虑到第i层中节点j路径的最小值依赖于第i-1层中的节点j-1和j。考虑到三角小头在上将计算反转,从低向上计算,既如图1.1中右边部分要达到6的位置只能从4或者1。思路清晰之后确定使用动态规划思想写这道题,定义dp数组,初始化为最底层的值,之后迭代更新dp数组值即可。

图1.1 反转过程

迭代公式:

\[dp[i] = \left\{\begin{matrix} arr[i] + min(dp[i],dp[i+1])& arr数组不为最底层 & \\ arr[i]& arr数组为最底层 & \end{matrix}\right.\]

Java解法复用最底层数组作为dp数组记录中间值:

public static int minimumTotal(List<List<Integer>> triangle) {
    if (triangle == null || triangle.size() == 0) return 0;
    List<Integer> dp = triangle.get(triangle.size() - 1);
    List<Integer> tmp;
    for (int i = triangle.size()-2; i >= 0; i--) {
        tmp = triangle.get(i);
        int j = 0;
        while (j < tmp.size()) {
            dp.set(j, tmp.get(j) + Math.min(dp.get(j),dp.get(j+1)));
            j++;
        }
    }
    return dp.get(0);
 }

小结:

​ 这是一道很典型的动态规划题,这里有一个简单的小技巧,就是将向下的问题转化成向上的问题,最终将解确定到dp数组的首位。

posted @ 2020-01-03 19:15  羊村灰太狼  阅读(319)  评论(0)    收藏  举报