【算法通关】| 最大路径和问题入门详解——以数学三角形为例题

关注微信公众号:怒码少年,回复关键词【电子书】可以免费获取计算机相关电子书

本文首发于:原文阅读-wx公众号:怒码少年

大家好,我是小码。

本篇是一道入门的最大路径和问题,使用的解决方法也是最简单,初学者请放心食用🍚。

数学三角形

题目描述

上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,请找到最大的和。

本题目来自蓝桥云课

路径上的每一步只可沿左斜线向下或右斜线向下走。

输入描述

输入的第一行包含一个整数N(1 <= N <= 100),表示三角形的行数。

接下来输入的N行都是组成数字三角形的数字,范围在0-99。

  • 5
  • 7
  • 3 8
  • 8 1 0
  • 2 7 4 4
  • 4 5 2 6 5

输出描述

从顶到底路径上最大的和。

30

思路分析

一般来说,这道题你看完题目之后,你的正常反应就是这个三角形好像一个树,那我就从树的根结点触发,每到一个结点都找这个结点中左右子结点中最大的那个不就好了吗?😏就像这样:

从第一层的7往下走,3和8的左右结点选最大的那个,所以走到8,8的左右子结点1和0选1,1的左右子结点7和4选7……就这样一直走到最后一层5。这样一条路径(7->8->1->7->5,暂且称为红色路径)就走完了,路径和是28,一切都是那么的完美。😁

但是我想说如果你这样做这道题,那你就大错特错啦~

注意看,如果我选择的是路径(7->3->8->7->5,暂且称为蓝色路径),路径和是30。

欸??不对啊,刚刚的红色路径每一次向下层走都是取得最大值,怎么你在第一步走的是3反而比走8的路径和还要大呢?🤔

根本原因:局部最优性不一定能推出全局最优性。

简单的来说,这道题求的是这个N行三角形中路径和的最大值,如果你是从顶层往底层走,你在第i层选择的最大子结点只能确定这个结点是这一层最大,但是你不能知道选择这个结点之后,这个结点本身和可以在后面的N-i层可以选择的路径和是不是最大的。

就拿刚刚的红色路径和蓝色路径比较,你在第2层选择的结点8是比第2层的结点3要大(局部最优性),但是结点8和之后可以选择的路径和(8->1->7->5)比结点3和之后可以选择的路径和(3->8->7->5)要小(推不出全局最优性)。

那可怎么办?每选择一步都会影响到后面的所有呀,又不能知道后面结点的情况。😭

这个时候,我们应该想想有没有一种办法可以不影响?🤔

答案是自底向上查找路径。

假设在这个例子中你已经走到N-1层的某一结点了,无论你前面的N-2层是怎么走的,接下来你一定会选择这个结点的左右结点中的最大值作为最后一步,使得你的路径和是最大的,如:

那么第N-1层应该选哪个结点呢?这是由第N-2层决定的,第N-2层决定的时候肯定要选择选择的结点可以使最后两层的和是最大的,因此我们可以在N-1层做决定的时候把最后两层的和求出供第N-2层选择,如图:

接下来的也是同理:

画板 7
画板 8 (2)
……

就这样一直到最后在加上根结点7就是最后的答案30。相当于自底向上选择路径:

代码实现

public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        //输入行数
        int n = scan.nextInt();
        int [][]a = new int[101][101];
        //输入数字三角形
        for(int i = 0 ; i < n;i++){
            for(int j = 0 ; j <= i; j++ ){
              a[i][j] = scan.nextInt();
            }
        }
        //从第n-1层开始比较子结点的大小
        for(int i = n-2; i >= 0 ; i--){
          for(int j = 0 ; j <= i ; j++){
            //选择子结点中交到的那个加当前层中
            if(a[i+1][j] >= a[i+1][j+1]){
              a[i][j]+=a[i+1][j];
            }else{
              a[i][j]+=a[i+1][j+1];
            }
          }
        }
        System.out.println(a[0][0]);
        scan.close();
    }
}

END

看到标题感觉有种很亲切的感觉,上次更【算法通关】系列是在两个月前了,这一次我要拿回属于我的一切💪(bushi

关注微信公众号:怒码少年,回复关键词【电子书】可以免费获取计算机相关电子书

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值