题目: 不同路径
来自智得网
方法一:动态规划
这种方法使用一个二维数组dp
来记录到达每个格子的不同路径数。初始化dp
数组的第一行和第一列为1,因为只能向右或向下移动。然后,从第二行第二列开始,对于每个格子,可以通过向右移动一步或向下移动一步到达。我们可以使用一个二维数组来保存从起点到当前位置的路径总数。具体来说,对于矩阵中的每个位置(i,j),路径总数等于上面的位置(i-1,j)和左边的位置(i,j-1)的路径总数之和。最后,返回dp
数组的最后一个元素即为结果。
因此,我们可以使用以下递推公式来计算路径总数:dp[i][j] = dp[i-1][j] + dp[i][j-1]
其中dp是一个二维数组,dp[i][j]表示从起点到(i,j)位置的路径总数。
#include <vector>
int uniquePaths(int m, int n) {
std::vector<std::vector<int>> dp(m, std::vector<int>(n, 1));
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
public int uniquePaths(int m, int n) {
int[][] dp = new int[m][n];
for (int i = 0; i < m; i++) {
dp[i][0] = 1;
}
for (int j = 0; j < n; j++) {
dp[0][j] = 1;
}
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
func uniquePaths(m int, n int) int {
dp := make([][]int, m)
for i := 0; i < m; i++ {
dp[i] = make([]int, n)
dp[i][0] = 1
}
for j := 0; j < n; j++ {
dp[0][j] = 1
}
for i := 1; i < m; i++ {
for j := 1; j < n; j++ {
dp[i][j] = dp[i-1][j] + dp[i][j-1]
}
}
return dp[m-1][n-1]
}
def uniquePaths(m, n):
dp = [[1] * n] + [[1] + [0] * (n-1) for _ in range(m-1)]
for i in range(1, m):
for j in range(1, n):
dp[i][j] = dp[i-1][j] + dp[i][j-1]
return dp[m-1][n-1]
function uniquePaths(m, n) {
const dp = new Array(m).fill(0).map(() => new Array(n).fill(0));
for (let i = 0; i < m; i++) {
dp[i][0] = 1;
}
for (let j = 0; j < n; j++) {
dp[0][j] = 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];
}
方法二:组合数学
不同路径问题可以转化为组合数学问题。机器人需要向下移动m-1
步,向右移动n-1
步,总共需要移动m+n-2
步。因此,问题可以转化为在这m+n-2
步中选择m-1
步或n-1
步的组合数。可以使用组合数的公式来计算。
(m+n−2)!/((m−1)!(n−1)!)
#include <vector>
int uniquePaths(int m, int n) {
long long result = 1;
for (int i = 1; i < n; i++) {
result = result * (m + i - 1) / i;
}
return (int)result;
}
public int uniquePaths(int m, int n) {
long result = 1;
for (int i = 1; i < n; i++) {
result = result * (m + i - 1) / i;
}
return (int)result;
}
func uniquePaths(m int, n int) int {
result := int64(1)
for i := 1; i < n; i++ {
result = result * int64(m+i-1) / int64(i)
}
return int(result)
}
from math import comb
def uniquePaths(m, n):
return comb(m + n - 2, n - 1)
function uniquePaths(m, n) {
let result = 1;
for (let i = 1; i < n; i++) {
result = result * (m + i - 1) / i;
}
return Math.floor(result);
}
方法三:深度优先搜索
这种方法使用递归来计算不同路径数。从起点出发,每次可以选择向右移动或向下移动,直到到达终点。递归函数dfs
用于计算从当前位置到达终点的路径数,通过递归调用向右和向下两个方向继续搜索。需要注意的是,为了避免重复计算,可以使用一个字典memo
来保存已经计算过的路径数。
int uniquePaths(int m, int n) {
if (m == 1 || n == 1) {
return 1;
}
return uniquePaths(m-1, n) + uniquePaths(m, n-1);
}
public int uniquePaths(int m, int n) {
if (m == 1 || n == 1) {
return 1;
}
return uniquePaths(m-1, n) + uniquePaths(m, n-1);
}
func uniquePaths(m int, n int) int {
if m == 1 || n == 1 {
return 1
}
return uniquePaths(m-1, n) + uniquePaths(m, n-1)
}
def uniquePaths(m, n):
if m == 1 or n == 1:
return 1
return uniquePaths(m-1, n) + uniquePaths(m, n-1)
function uniquePaths(m, n) {
if (m === 1 || n === 1) {
return 1;
}
return uniquePaths(m-1, n) + uniquePaths(m, n-1);
}