首页 > 代码库 > 【LeetCode120】Triangle[DP]

【LeetCode120】Triangle[DP]

120. Triangle

 

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).

 

题目的意思很明确,就是要求找出最短路径,类似于二叉树的最小路径,所以马上就想到了用递归的方法

 

分析:

 

设f(n)为当前路径总和最小值,a[i][j]为三角形, 0<n<a.length

当 n = 1时:

f(n) = a[0][0] (显然)

当 1<n<a.size时,

f(n) =Min{f(n-1) + a[n][j],f(n-1) + a[n][j+1]}, 0<j<a[n].length-1

当 n>=a.size时 ,

f(n) = a[n][j]

 

老规矩,用JAVA

Recursive version(超时版本):

 

    public int minimumTotal( List<List<Integer>> triangle ) {
        return goRec( triangle, 0, 0 );
    }

    private int goRec( List<List<Integer>> triangle, int index, int row ) {
        if( row == triangle.size() - 1 ) {
            return triangle.get( row ).get( index );
        }
        int nextRow = row + 1;
        return triangle.get( row ).get( index ) + Math.min( goRec( triangle, index, nextRow ), goRec( triangle, ++index, nextRow ) );
    }

 

 

一提上去,果不其然,最后的test case过不了,会超时(TLE)。

无奈,只能改用动态规划(Dp)的方法来做。

用dp的方法是用一个n*n的矩阵来表示当前值。

根据上面的分析,很容易就能写出状态转移方程:

      

dp[i][j]= Min{dp[i-1][j] + triangle[i][j],dp[i-1][j] + triangle[i][j+1]}

 

Ps.注意边界值,即 j==0和 j==i时的情况。

 

 

Ac Code:

 

    public int minimumTotal( List<List<Integer>> triangle ) {
        int[][] dp = new int[ triangle.size() ][ triangle.size() ];
        dp[ 0 ][ 0 ] = triangle.get( 0 ).get( 0 );

        for( int i = 1; i < triangle.size(); i++ ) {
            List<Integer> tempList = triangle.get( i );
            for( int j = 0; j < i + 1; j++ ) {
                if( j == 0 ) {
                    dp[ i ][ j ] = dp[ i - 1 ][ j ] + tempList.get( j );
                } else if( j == i ) {
                    dp[ i ][ j ] = dp[ i - 1 ][ j - 1 ] + tempList.get( j );
                } else {
                    dp[ i ][ j ] = Math.min( dp[ i - 1 ][ j ] + tempList.get( j ), dp[ i - 1 ][ j - 1 ] + tempList.get( j ) );
                }
            }
        }

        int result = Integer.MAX_VALUE;
        int length = dp[ triangle.size() - 1 ].length;
        for( int i = 0; i < length; i++ ) {
            int temp = dp[ length - 1 ][ i ];
            if( temp < result ) {
                result = temp;
            }
        }
        return result;
    }

 

暂时没有想到更好的方法,我觉得应该可以优化,毕竟题目中存在Bounus point(空间复杂度是O(n)),我的做法明显是复杂度似乎是O(n)?

 

【LeetCode120】Triangle[DP]