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)?
时间: 2024-11-04 19:46:19