一个机器人位于一个
m x n
网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
解法1 记忆化搜索
思路
使用dfs的思路就是向下或向右探索,dfs(x, y)
表示 从 (x, y)
出发到终点的路径数量;
所以 x,y
的路径数量要通过 dfs(x + 1, y) + dfs(x, y + 1)
计算出来。
代码
function uniquePaths(m: number, n: number): number {
const memo = Array.from({length: m}, () => Array(n).fill(-1));
const dfs = (x, y) => {
if (x >= m || y >= n) return 0;
if (x === m - 1 && y === n - 1) return 1;
if (memo[x][y] !== -1) return memo[x][y];
memo[x][y] = dfs(x + 1, y) + dfs(x, y + 1);
return memo[x][y];
}
return dfs(0, 0);
};
时空复杂度
时间复杂度:O(m * n)
空间复杂度:O(m * n)
解法2 动态规划
思路
如果用动态规划去思考的话,首先定义 dp 数组是干嘛的。 dp[i][j]
代表了从该点到达终点的路径数量。
和上面的 dfs 相反,所以状态转移方程也不一样即 dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
代码
function uniquePaths(m: number, n: number): number {
const dp = Array.from({length: m}, () => Array(n).fill(1));
for (let i = 1; i < m; i++) {
for (let j = 1; j < n; j++) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
return dp[m - 1][n - 1];
};
时空复杂度
时间复杂度:O(m * n)
空间复杂度:O(m * n)