1 题目

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.

2 思路

这是一个动态规划题,每行的数据数对应行数,设F[m,n]表示到达第m行,第n列的最小代价,那么有

F[m,n]=min{F[i-1,j]+b,F[i-1,j-1]+b},其中b为第m行,第n列的数

那么边界值怎么处理呢?

我是设置正常值从1开始,0和最后一个值的后一位为IntMax。

 

这道题是我自己想出来的。

3 代码

①空间O(n^2),第一次想到的是这个

public int minimumTotal(List<List<Integer>> triangle){
        int lineNumber = triangle.size();
        Integer[][] F = new Integer[lineNumber][lineNumber+2];
        //F(a,b) = min{F(a-1,b-1)+b,F(a-1,b)+b} F(a,b)表示 第a行第b个的最小代价
        //set F(a,0) to MAX, F(a,B) to MAX , where B = triangle.get(a).size()+1, 0<=a<lineNumber;
        //set the initial value
        
        F[0][1] = triangle.get(0).get(0);
        for (int i = 0; i < lineNumber; i++) {
            F[i][0] = Integer.MAX_VALUE;
            int lineSize = triangle.get(i).size() + 1;
            F[i][lineSize] = Integer.MAX_VALUE;
        }
//        long former = 0;
        //dynamic programming
        for (int i = 1; i < lineNumber; i++) {
            List<Integer> row = triangle.get(i);
            int rowSize = row.size();
            for (int j = 1; j <= rowSize; j++) {
                F[i][j] = Math.min(F[i-1][j-1], F[i-1][j]) + row.get(j-1);
            }
        }
        
        int min = F[lineNumber-1][1];
        for (int i = 1; i <= lineNumber; i++) {
            int temp = F[lineNumber-1][i];
            if(temp < min){
                min = temp;
            }
        }
        
        return min;
    }

②空间o(n),改进了一下

public int minimumTotal2(List<List<Integer>> triangle){
        int lineNumber = triangle.size();
        Integer[][] F = new Integer[2][lineNumber+2];
        //F(a,b) = min{F(a-1,b-1),F(a-1,b)} + b;  F(a,b)represent the minValue of the a row b list
        
        //set the initial value and the boundary value
        F[0][0] = Integer.MAX_VALUE;
        F[0][1] = triangle.get(0).get(0);
        F[0][2] = Integer.MAX_VALUE;
        
        //dynamic programming
        for (int i = 1; i < lineNumber; i++) {
            List<Integer> row = triangle.get(i);
            int rowSize = row.size();
            for (int j = 1; j <= rowSize; j++) {
                F[1][j] = Math.min(F[0][j-1], F[0][j]) + row.get(j-1);
            }
            F[1][0] = Integer.MAX_VALUE;
            F[1][rowSize+1] = Integer.MAX_VALUE;
            for (int j = 0; j <= rowSize+1; j++) {
                F[0][j] = F[1][j];
            }
        }
        
        int min = F[lineNumber > 1 ? 1 : 0][1];
        for (int i = 1; i <= lineNumber; i++) {
            int temp = F[lineNumber > 1 ? 1 : 0][i];
            if(temp < min){
                min = temp;
            }
        }
        
        return min;
    }