classSolution { public: intuniquePaths(int m, int n){ vector<vector<int>> f(m, vector<int>(n)); for (int i = 0; i < m; ++i) { f[i][0] = 1; } for (int j = 0; j < n; ++j) { f[0][j] = 1; } for (int i = 1; i < m; ++i) { for (int j = 1; j < n; ++j) { f[i][j] = f[i - 1][j] + f[i][j - 1]; } } return f[m - 1][n - 1]; } };
[sol1-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
classSolution { publicintuniquePaths(int m, int n) { int[][] f = newint[m][n]; for (inti=0; i < m; ++i) { f[i][0] = 1; } for (intj=0; j < n; ++j) { f[0][j] = 1; } for (inti=1; i < m; ++i) { for (intj=1; j < n; ++j) { f[i][j] = f[i - 1][j] + f[i][j - 1]; } } return f[m - 1][n - 1]; } }
[sol1-Python3]
1 2 3 4 5 6 7 8
classSolution: defuniquePaths(self, m: int, n: int) -> int: f = [[1] * n] + [[1] + [0] * (n - 1) for _ inrange(m - 1)] print(f) for i inrange(1, m): for j inrange(1, n): f[i][j] = f[i - 1][j] + f[i][j - 1] return f[m - 1][n - 1]
[sol1-Golang]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
funcuniquePaths(m, n int)int { dp := make([][]int, m) for i := range dp { 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] }
[sol1-C]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
intuniquePaths(int m, int n) { int f[m][n]; for (int i = 0; i < m; ++i) { f[i][0] = 1; } for (int j = 0; j < n; ++j) { f[0][j] = 1; } for (int i = 1; i < m; ++i) { for (int j = 1; j < n; ++j) { f[i][j] = f[i - 1][j] + f[i][j - 1]; } } return f[m - 1][n - 1]; }
[sol1-JavaScript]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
var uniquePaths = function(m, n) { const f = newArray(m).fill(0).map(() =>newArray(n).fill(0)); for (let i = 0; i < m; i++) { f[i][0] = 1; } for (let j = 0; j < n; j++) { f[0][j] = 1; } for (let i = 1; i < m; i++) { for (let j = 1; j < n; j++) { f[i][j] = f[i - 1][j] + f[i][j - 1]; } } return f[m - 1][n - 1]; };
复杂度分析
时间复杂度:O(mn)。
空间复杂度:O(mn),即为存储所有状态需要的空间。注意到 f(i, j) 仅与第 i 行和第 i-1 行的状态有关,因此我们可以使用滚动数组代替代码中的二维数组,使空间复杂度降低为 O(n)。此外,由于我们交换行列的值并不会对答案产生影响,因此我们总可以通过交换 m 和 n 使得 m \leq n,这样空间复杂度降低至 O(\min(m, n))。
classSolution { public: intuniquePaths(int m, int n){ longlong ans = 1; for (int x = n, y = 1; y < m; ++x, ++y) { ans = ans * x / y; } return ans; } };
[sol2-Java]
1 2 3 4 5 6 7 8 9
classSolution { publicintuniquePaths(int m, int n) { longans=1; for (intx= n, y = 1; y < m; ++x, ++y) { ans = ans * x / y; } return (int) ans; } }
[sol2-Python3]
1 2 3
classSolution: defuniquePaths(self, m: int, n: int) -> int: return comb(m + n - 2, n - 1)
[sol2-Golang]
1 2 3
funcuniquePaths(m, n int)int { returnint(new(big.Int).Binomial(int64(m+n-2), int64(n-1)).Int64()) }
[sol2-C]
1 2 3 4 5 6 7
intuniquePaths(int m, int n) { longlong ans = 1; for (int x = n, y = 1; y < m; ++x, ++y) { ans = ans * x / y; } return ans; }
[sol2-JavaScript]
1 2 3 4 5 6 7
var uniquePaths = function(m, n) { let ans = 1; for (let x = n, y = 1; y < m; ++x, ++y) { ans = Math.floor(ans * x / y); } return ans; };
复杂度分析
时间复杂度:O(m)。由于我们交换行列的值并不会对答案产生影响,因此我们总可以通过交换 m 和 n 使得 m \leq n,这样空间复杂度降低至 O(\min(m, n))。