#动态规划 LeetCode 120 三角形最小路径和

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

例如,给定三角形:

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

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

说明:

如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。

思路:

接着上一题的状态转移继续说

  • 动态规划问题,重中之重就是找到状态转移方程,而状态转移方程很重要的一点就是明确函数的意义所在,以及记录结果的数据结构。
  • 比如上一题中的F(n)就是走到第n阶的方法数。我个人更倾向于把它描述为,我们最后一步走到第n阶的全部走法。
  • 而这一题相对就复杂的地方就在于,我们记录结果的数据结构不是一个简单的数字了,而是一个二维的数组(java这里是List<List>)
  • 在问题开始之前,对应的二维数组储存的是从上一节,走到这一节,需要的步数。
  • 我们自上而下 ,开始寻找状态方程很容易想到的是最顶层的走法为F(0,0)= F(1,0)+F(1,1)
  • 本质上状态方程变为F(i,j) = F(i+1 ,j)+F(i+1, j+1),只有这两个位置为相邻的。
  • 得到了状态转移方程我们就可以自底向上开始思考了。F(n-2,0) = F(n-1,0)+ F(n-1,1)。。。
  • 问题的重点来了,这里并不是一个一维的过程,我们需要一个和初始数组类似的二维数组,依次记录结果。我们新的数组的所代表的意义为:从下倒上,走到当前位置所走最少步数。
  • 而我们从下倒上和从上到下的长度是一致的。所以每次遇到新的节点,我们仅仅需要在可以到达他的方法中选取最小结果记录即可。
  • 所以我们使用迭代的方法,自下而上依次遍历并且记录。最后走到顶点的结果即F(0,0)即为所求。
class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        int n = triangle.size();
        if(n == 0)
            return 0;
        
        for(int i = n-1 ; i>=0 ; i--)
            for(int j=0 ; j<triangle.get(i).size(); j++ ){
                if(i!=n-1)
                    triangle.get(i).set(j , (int)Math.min( triangle.get(i+1).get(j),triangle.get(i+1).get(j+1))+triangle.get(i).get(j) );
            }
        
        return triangle.get(0).get(0);
    }
}

猜你喜欢

转载自www.cnblogs.com/rainxbow/p/9695460.html