动态规划(4)--------仍然是一个简单的例子

给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。

例如,给定三角形:

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]

自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/triangle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

       经过上几次的分析,我们应该知道了,动态规划的关键是找到状态转移方程。对于此问题,我想状态转移方程是很明显的。节点[i,j],选择min([i-1,j],[i-1,j-1]),然后加上自己的数。注意,题干说的相邻指的是节点[i,j]和节点[i+1,j],[i+1,j+1]相邻。那么此处将会有两种解法,自顶向下和自底向上,显然,对于自顶向下,我们需要选择min([i-1,j],[i-1,j-1]),但是此处存在一个问题,即,上层比下层长度短,那么越界问题必然需要注意,此外还有j-1,需要单独讨论j=0的情况,

      下面先给出自顶向下的代码

public int minimumTotal(List<List<Integer>> triangle) {
        int rows = triangle.size();
        if(rows == 0)
            return 0;
        int[][] dp = new int[rows][rows];
        dp[0][0] = triangle.get(0).get(0);
        for(int i=1;i<triangle.size();++i){
            List<Integer> array = triangle.get(i);
            for(int j=0;j<array.size();++j){
                if(j>0 && j<array.size()-1){
                    dp[i][j] = Math.min(dp[i-1][j-1],dp[i-1][j]) + array.get(j);
                }else {
                    if(j == 0)
                        dp[i][j] = dp[i-1][j] + array.get(j);
                    if(j == array.size()-1)
                        dp[i][j] = dp[i-1][j-1] + array.get(j);
                }
            }
        }
        int ans = dp[rows-1][0];
        for(int i=1;i<rows;++i)
            ans = ans<=dp[rows-1][i]?ans:dp[rows-1][i];
        return ans;

    }

      对于自底向上的传递,由于相邻规则的限制,无需考虑数组越界的问题,其思路和上述一致。

public int minimumTotal(List<List<Integer>> triangle) {
        int rows = triangle.size();
        if(rows == 0)
            return 0;
        int cols = triangle.get(rows-1).size();
        int[][] dp = new int[rows+1][rows+1];               
        for (int i=triangle.size()-1;i>=0;--i){
            List<Integer>array = triangle.get(i);
            for(int j=0;j<array.size();++j){
                dp[i][j] = Math.min(dp[i+1][j],dp[i+1][j+1])+array.get(j);
            }
        }
        return dp[0][0];
    }

       可以看出来,自底向上明显比自顶向下简介的多。

       此外,上述代码的空间复杂度可以进一步降低。有兴趣可以试试

猜你喜欢

转载自www.cnblogs.com/establish/p/11802256.html