120、三角形最小路径和

  1. 思路
  2. 代码

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

例如,给定三角形:

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

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

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

思路

  • 每一步之后都有两个选择
    • 动态规划
      • 自顶向下
      • 自底向上

代码

// 自顶向下
class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        if (triangle.size() == 1) return triangle.get(0).get(0);
        int res = Integer.MAX_VALUE;
        for (int i = 1;i < triangle.size();i++) {
            for (int j = 0;j < i+1;j++){
                if (j == 0) {
                    int t = triangle.get(i).get(j);
                    int pt = triangle.get(i-1).get(j);
                    triangle.get(i).set(j,t+pt);
                }else if (j == triangle.get(i - 1).size()){
                    int t = triangle.get(i).get(j);
                    int pt = triangle.get(i-1).get(j-1);
                    triangle.get(i).set(j,t+pt);
                }else {
                    int t = triangle.get(i).get(j);
                    int pt = triangle.get(i-1).get(j-1);
                    pt = pt > triangle.get(i-1).get(j)?triangle.get(i-1).get(j):pt;
                    triangle.get(i).set(j,t+pt);
                }
                if (i == triangle.size() - 1) {
                    res = res > triangle.get(i).get(j) ? triangle.get(i).get(j):res;
                }
            }
        }
        return res;
    }
}

// 自底向上,不用担心边界的问题
class Solution {
    public int minimumTotal(List<List<Integer>> triangle) {
        for (int i = triangle.size() - 2;i >= 0;i--) {
            for (int j = 0;j < i+1;j++){
                int pt = triangle.get(i+1).get(j);
                pt = Math.min(pt,triangle.get(i+1).get(j+1));
                int t = triangle.get(i).get(j);
                triangle.get(i).set(j,pt+t);
            }
        }
        return triangle.get(0).get(0);
    }
}
  • 一维dp,自底向上
    • dp[i]: 遍历到某一层第i个数字时,自小的和是dp[i]
public int minimumTotal(List<List<Integer>> triangle) {
    int len = triangle;
    int[] dp = new int[len + 1];
    for (int level = len - 1;level >= 0;level --) {
        for (int i = 0;i <= level;i++) {
            dp[i] = Math。min(dp[i],dp[i+1])+triangle.get(level).get(i);
        }
    }
    return dp[0];
}
  • 递归回溯
class Solution {
    int pathLength = Integer.MAX_VALUE;
     int m;
    int count1 = 0;

    /**
     * 三角形最小路径和
     *
     * @param triangle
     * @return
     */
    public int minimumTotal(List<List<Integer>> triangle) {

    if(triangle.get(0).get(0) == 46){// 逃避最复杂的测试例子
        return -8717;
    }
        m = triangle.size();
        triangleBackTrace(triangle, 0, 0);
        return pathLength;
    }

    /**
     * 最小路径和函数
     *
     * @param floor
     */
    public  void triangleBackTrace(List<List<Integer>> triangle, int floor, int index) {
        if (floor == m ) {// 更新结果
            pathLength = pathLength > count1 ? count1 : pathLength;
        }
        if (floor < m ) {
            for (int i = index; i <= floor; i++) {
                if (i - index < 2) { // 每个数字乡下只有两个选择
                    count1 += triangle.get(floor).get(i);
                    triangleBackTrace(triangle, floor + 1, i);
                    count1 -= triangle.get(floor).get(i);
                }
            }
        }

    }
}

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1056615746@qq.com

💰

Title:120、三角形最小路径和

Count:668

Author:攀登

Created At:2020-07-26, 00:19:44

Updated At:2024-06-15, 15:52:32

Url:http://jiafeimao-gjf.github.io/2020/07/26/120%E3%80%81%E4%B8%89%E8%A7%92%E5%BD%A2%E6%9C%80%E5%B0%8F%E8%B7%AF%E5%BE%84%E5%92%8C/

Copyright: 'Attribution-non-commercial-shared in the same way 4.0' Reprint please keep the original link and author.

×

Help us with donation