三角形最小路径和

59 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情

三角形最小路径和

描述

image.png

如上图所示,是个由数字组成的三角形状。

从第一层到最后一层的路径规则是:

  • 只能往下走,不能平移
  • 除最后一层外,任一层的某个数都可以往下连接与之最近的两个数,再依次继续下行

按照这样的规则走,总路径就有Math.pow(2, n-1)种走法。

我们需要做的是找出这么多条路径中的最小路径和。

分析

最直接的方法就是按描述中说的,先分别找出Math.pow(2, n-1)种路径求和,然后取最小值返回。这样需要保存的数据量是不是会很大,因为你得先枚举出这么多条路径值,在没有计算出最后一个值之前,不可能排除掉任何一项,只能都枚举出来再求值。很显然,这种方式不是最佳的。

第二种方式:

我们先从倒数第二层开始计算,因为最后一层不用计算,在倒数第二层,对每一个值进行循环,取每个数对应2条路径中的最小值,然后与自己求和,在存入原数组中,这样我们仅不断改变原数组的值,再一直往上走,直到第一层,就是我们要得到的结果。

在这里我们需要对某个节点与其俩相邻数的位置来找规律。例如:当前节点是6(如上图),也就是第三行第一列,与6相邻的下一行节点分别是第四行第一列和第四行第二列,规律也就很明显了。

row[i][j] += Math.min(row[i+1][j] + row[i+1][j+1]) // 新的节点值

程序实现

var minimumTotal = function(triangle) {
  // 当三角形就一个数据的时候,直接返回
  if (triangle.length === 1) return triangle[0][0]
  // 从最后一层开始计算
  for (let i = triangle.length - 2; i >= 0; i--) {
    for (let j = 0; j < i + 1; j++) {
      triangle[i][j] += Math.min(triangle[i+1][j], triangle[i+1][j+1])
    }
  }
  return triangle[0][0]
};