120三角形最小路径和

题目描述

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

例如,给定三角形:

[

[2],

[3,4],

[6,5,7],

[4,1,8,3]

]

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

说明:

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

思路分析

状态:索引号。

选择:下一行相邻,通俗说就是 i 或者 i+1 位置。

状态转移:

  1. 自顶向下:curLevel[j] = Math.min(curLevel[j - 1], curLevel[j]) + triangle.get(i).get(j);
    - 此时需要考虑base case,第0列只能继承正上方,最后一列只能继承左上方。
  2. 自底向上:curLevel[j] = Math.min(curLevel[j], curLevel[j + 1]) + triangle.get(i).get(j);
    - 不许考虑base case,最后返回[0][0]元素。

空间复杂度:

  • 用二维数组,保存路径上计算的所有的路径和,O(n^2);
  • 用一维数组,我们发现计算第 i 行只用 i+1 行的元素,所以只用数组存储一行数据,重复覆盖;
  • 原地修改,用原来的矩阵,直接自底向上覆盖。

代码实现

public static int minimumTotal(List<List<Integer>> triangle) {
        if (triangle == null || triangle.size() == 0 || triangle.get(0) == null || triangle.get(0).size() == 0) {
            return 0;
        }
        //O(n)
        int n = triangle.size();
        int level = 2;
        int[] curLevel = new int[n];
        curLevel[0] = triangle.get(0).get(0);
        int min = Integer.MAX_VALUE;
        //自顶向下
        /*for (int i = 1; i < n; i++) {
            for (int j = level - 1; j >= 0; j--) {
                if (j == level - 1) {
                    curLevel[j] = curLevel[j - 1] + triangle.get(i).get(j);
                    continue;
                }
                if (j == 0) {
                    curLevel[j] = curLevel[j] + triangle.get(i).get(j);
                    continue;
                }
                curLevel[j] = Math.min(curLevel[j - 1], curLevel[j]) + triangle.get(i).get(j);
            }
            level++;
        }
        for (int num : curLevel) {
            min = num < min ? num : min;
        }
        return min;*/
        //自底向上
        level = n - 1;
        for (int i = 0; i < triangle.get(level).size(); i++) {
            curLevel[i] = triangle.get(level).get(i);
        }
        for (int i = n - 2; i >= 0; i--) {
            for (int j = 0; j < level; j++) {
                curLevel[j] = Math.min(curLevel[j], curLevel[j + 1]) + triangle.get(i).get(j);
            }
            level--;
        }
        return curLevel[0];
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值