动态规划-数字三角形 JavaScript

数字三角形问题

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

规则:

  1. 在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大
  2. 只能往坐下或者右下走,如,第二行的 3,只能往第三行的 8 和 第三行的 1 走,走第三行的0是不行的(我开始这个规则也理解错误)
  3. 用眼睛看上往下自己加是错误的,应该从下往上加 (我开始也理解错了)

解题方法

1 、递归解法 不必须要的重复计算,低效 O (2的n次方)

function maxSumUsingRecursive(arr, i, j) {
  let rowIndex = arr.length;
  if (i == rowIndex - 1) {
    return arr[i][j];
  } else {
    // 顶点的值+max(左侧支路的最大值,右侧支路的最大值)
    return triangle[i][j] + Math.max(maxSumUsingRecursive(arr, i + 1, j), maxSumUsingRecursive(arr, i + 1, j + 1));
  }
}

2、递归解法 缓存sum

function MaxSumCache(i, j, arr) {
  const n = arr.length - 1;
  let cache;

  // 初始化一个缓存
  if (MaxSumCache.cache) {
    cache = MaxSumCache.cache
  } else {
    let _cache = []
    for (let i = 0; i <= n; i++) {
      _cache.push([])
    }
    cache = _cache
    MaxSumCache.cache = cache;
  }

  //这个数字的最大值已经被求出来了
  if (cache[i][j] != undefined) {
    return cache[i][j];
  }
  //如果i==n,那就说明它已经是最后一行的那个数字了, 那最大和就是那个数字它自己
  if (i == n) {
    cache[i][j] = arr[i][j];
  } else {
  //否则就要算一下 它正下方的那个数字走到底边得到的最大和是什么
    cache[i][j] = Math.max(MaxSumCache(i + 1, j, arr), MaxSumCache(i + 1, j + 1, arr)) + arr[i][j];
  }
  return cache[i][j];
}

3 、 递推法 从最后一行,往上算, 避免了重复运算,O(n2)

  function ditui(arr, i, j) {
    let n = arr.length, dp = [];
    let m = n - 1;
    // 把结果全部放到dp数组,从数组最后一层递推上去
    dp[m] = [...arr[m]];
    for (let a = m - 1; a >= 0; a--) {
      dp[a] = []
      for (let b = 0; b <= a; b++) {
        dp[a][b] = arr[a][b] + Math.max(dp[a+1][b], dp[a+1][b+1])
      }
    }
    return dp[i][j]
  }
发布了40 篇原创文章 · 获赞 12 · 访问量 860

猜你喜欢

转载自blog.csdn.net/qq_29334605/article/details/105389151