120 Triangle

update 2018-10-07 22:12:28

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.

Basic Idea:

  • 思路 1:divide & conquer

    从上往下递归,每次计算下方两个元素为起点到最后一层的最小路径和,输出最小的。注意其中有很多重复操作,可以使用map来去重。

    Java Code:

    class Solution {
        Map<String, Integer> memory = new HashMap<>();
        public int minimumTotal(List<List<Integer>> triangle) {
            if (triangle.size() == 0) return 0;
            int left = helper(triangle, 1, 0);
            int right = helper(triangle, 1, 1);
            return Math.min(left, right) + triangle.get(0).get(0);
        }
    
        private int helper(List<List<Integer>> triangle, int row, int col) {
            if (triangle.size() == row) return 0;
            Integer ret = memory.get(row + "," + col);
            if (ret != null) return ret;
            int left = helper(triangle, row + 1, col);
            int right = helper(triangle, row + 1, col + 1);
            ret = Math.min(left, right) + triangle.get(row).get(col);
            memory.put(row + "," + col, ret);
            return ret;
        }
    }
    
  • 思路 2:DP

    通过观察我们发现每层比下一层都少一个元素,于是我们可以利用一个长度等于最后一行数组的dp数组进行推导,每次推导出上面一层每个元素对应的最小路径和,最终dp[0]就是解。

      例如之前题中所给的例子,每次推导出上面一层每个元素对应的最小的路径和:
    
      首先,dp数组为 [4,1,8,3] (最后一层为 Base Case)
      然后倒数第二层,dp数组为 [7,6,10,x] (4+61+6 中最小的,1+58+5 中最小的, 7+87+3 中最小的)
      倒数第三层:dp数组为 [9,10,x,x] (3+73+6 中最小的, 4+64+10 中最小的)
      最上面一层 dp数组为 [11,x,x,x] (9+210+2 中最小的)
      最终结果就是 dp[0]==11
    

    Java Code:

    class Solution {
        public int minimumTotal(List<List<Integer>> triangle) {
            if (triangle.size() == 0) return 0;
            else if (triangle.size() == 1) return triangle.get(0).get(0);
    
            int[] dp = new int[triangle.size()];
    
            // initialize the dp array with values of the bottom layer
            for (int i = 0; i < triangle.size(); ++i) dp[i] = triangle.get(triangle.size() - 1).get(i);
    
            for (int i = triangle.size() - 2; i >= 0; --i) {
                for (int j = 0; j < triangle.get(i).size(); ++j) {
                    dp[j] = Math.min(dp[j], dp[j + 1]) + triangle.get(i).get(j);
                }
            }
            return dp[0];
        }
    }
    

results matching ""

    No results matching ""