剑指 offer 动态规划算法题:不同路径

文章介绍了如何使用动态规划方法计算一个机器人在mxn网格中从左上角到达右下角的不同路径数。通过状态转移方程`dp(i,j)=dp(i-1,j)+dp(i,j-1)`,以及降维优化空间复杂度的策略,实现更高效的解决方案。
摘要由CSDN通过智能技术生成

题目: 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。1 <= m, n <= 100。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径?

uniquePaths(3, 7); // 28

uniquePaths(3, 2); // 3

uniquePaths(7, 3); // 28

uniquePaths(3, 3); // 6

分析:

        动态规划法, 其状态转移方程为  dp(i, j) = dp(i - 1, j) + dp(i, j - 1);  dp(i, 0) = 1; dp(j, 0) = 1;dp(i, j)表示到达第i行第j列有多少条路径(i, j 均从0开始)。

        降维打击动态规划法,即优化空间复杂度,使用dp表(paths),即滚动数组,初始均为 1。数组的元素总是等于当前列上一行(paths[j]) + 当前行上一列(paths[j - 1])。

求解:

export function uniquePaths(m: number, n: number): number {
  if (m < 1 || n < 1) {
    throw new TypeError('m, n 必须均不小于1');
  }
  const cache = new Map<string, number>();
  const getPaths = (i: number, j: number): number => {
    if (i === 0 || j === 0) {
      return 1;
    }
    const key = `${i}-${j}`;
    const cachePaths = cache.get(key);
    if (cachePaths) {
      return cachePaths;
    }
    const paths = getPaths(i, j - 1) + getPaths(i - 1, j);
    cache.set(key, paths);
    return paths;
  };
  return getPaths(m - 1, n - 1);
}

export function uniquePaths2(m: number, n: number): number {
  if (m < 1 || n < 1) {
    throw new TypeError('m, n 必须均不小于1');
  }
  const paths: number[][] = new Array(m).fill(0).map(() => new Array(n)); // dp表
  for (let i = 0; i < m; i++) {
    for (let j = 0; j < n; j++) {
      if (i === 0 || j === 0) {
        paths[i][j] = 1;
      } else {
        paths[i][j] = paths[i - 1][j] + paths[i][j - 1];
      }
    }
  }
  return paths[m - 1][n - 1];
}

// 优化空间复杂度:降维打击
export function uniquePaths3(m: number, n: number): number {
  if (m < 1 || n < 1) {
    throw new TypeError('m, n 必须均不小于1');
  }
  const paths: number[] = new Array(n).fill(1); // dp表,滚动数组,初始均为 1
  for (let i = 1; i < m; i++) {
    for (let j = 1; j < n; j++) {
      paths[j] = paths[j] + paths[j - 1]; // 总是等于当前列上一行(paths[j]) + 当前行上一列(paths[j - 1])
    }
  }
  return paths[n - 1];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

薛定谔的猫96

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值