leetcode_120_三角形最小路径和

题目:

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

相邻的结点 在这里指的是 下标 与 上一层结点下标 相同或者等于 上一层结点下标 + 1 的两个结点。

 

例如,给定三角形:

[
     [2],
    [3,4],
   [6,5,7],
  [4,1,8,3]
]
自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

 

说明:

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

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


思路:这个题比较简单,典型的动态规划问题。实现的时候,我从底部开始向上dp。当然从上到下也可。

在状态转移的时候,可以重复使用一个一维状态数组dp,因为上次的状态在这次使用过后就没有用处了,所以直接在原状态dp[i]处即可更新为新的dp[i]。因为:只能移动到下一行相邻的点。

即:dp[i] = min(dp[i]+ob[i], dp[i+1]+ob[i])。

将给出的三角形转化为一个n*n矩阵很好理解该方程。

其中,左边的dp[i]表此处的状态,现在还没有更新。

右边的dp[i]事实上指的是当前层的下一层的第i个位置处的状态。同理,dp[i+1]指的是当前层的下一层的第i+1个位置处的状态。

因为当你处在一个位置时,要么向下走,要么向斜右下方走。这两个方向分别对应等式右边的两个dp:dp[i]与dp[i+1]。

比如,当处于值为5的位置时,其状态只能有下面的值为1或者值为8的位置处的状态转变而来。


实现:

JAVA版:

package leetcode;

import java.util.ArrayList;
import java.util.List;

/*
USER:LQY
DATE:2020/7/14
TIME:9:37
*/
public class leetcode_120 {

    public static void main(String []args){
        List<Integer> inner1 = new ArrayList<>();
        List<Integer>inner2 = new ArrayList<>();
        List<Integer>inner3 = new ArrayList<>();
        List<Integer>inner4 = new ArrayList<>();
        List<List<Integer>> outer = new ArrayList<>();
        inner1.add(2);
        inner2.add(3);inner2.add(4);
        inner3.add(6);inner3.add(5);inner3.add(7);
        inner4.add(4);inner4.add(1);inner4.add(8);inner4.add(3);
        outer.add(inner1);
        outer.add(inner2);
        outer.add(inner3);
        outer.add(inner4);
        new leetcode_120().minimumTotal(outer);
    }

    public int minimumTotal(List<List<Integer>> triangle) {
//        int ans = 0;
        int len = triangle.size();
        int []dp = new int[len];
        List<Integer> temp = triangle.remove((len-1));
        int index = 0;
        for(int i: temp){
            dp[index++] = i;
        }
        for(int i = 0;i < len;i++)
            System.out.print(dp[i]+" ");
        System.out.println();
        int size = len - 1;
        while(size > 0){
            temp = triangle.remove(size-1);

            index = 0;
            for(int i : temp){
               dp[index] = Math.min(i+dp[index], i+dp[index+1]);
               index++;
            }

            for(int i = 0;i < size;i++)
                System.out.print(dp[i]+" ");
            System.out.println();
            size--;

        }


        return dp[0];
    }
}

Python版:

class Solution:
    def minimumTotal(self, triangle: List[List[int]]) -> int:
        lens = len(triangle)
        dp = triangle[lens-1][:]
        size = lens - 1
        
        while(size > 0):

            index = 0
            for i in triangle[size-1][:]:
                dp[index] = min(i+dp[index], i+dp[index+1])
                index += 1
            size -= 1
        return dp[0]

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值