Skip to content

Commit bac0383

Browse files
authored
feat: add solutions to lc/lcof2 problems: Unique Paths (doocs#1481)
lc No.0062 & lcof2 No.098.Unique Paths
1 parent 9686c56 commit bac0383

17 files changed

+569
-124
lines changed

lcof2/剑指 Offer II 098. 路径的数目/README.md

+294-30
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,29 @@
6262

6363
<!-- 这里可写通用的实现逻辑 -->
6464

65-
动态规划
65+
**方法一:动态规划**
6666

67-
假设 `dp[i][j]` 表示到达网格 `(i,j)` 的路径数,则 `dp[i][j] = dp[i - 1][j] + dp[i][j - 1]`
67+
我们定义 $f[i][j]$ 表示从左上角走到 $(i, j)$ 的路径数量,初始时 $f[0][0] = 1$,答案为 $f[m - 1][n - 1]$。
68+
69+
考虑 $f[i][j]$:
70+
71+
- 如果 $i \gt 0$,那么 $f[i][j]$ 可以从 $f[i - 1][j]$ 走一步到达,因此 $f[i][j] = f[i][j] + f[i - 1][j]$;
72+
- 如果 $j \gt 0$,那么 $f[i][j]$ 可以从 $f[i][j - 1]$ 走一步到达,因此 $f[i][j] = f[i][j] + f[i][j - 1]$。
73+
74+
因此,我们有如下的状态转移方程:
75+
76+
$$
77+
f[i][j] = \begin{cases}
78+
1 & i = 0, j = 0 \\
79+
f[i - 1][j] + f[i][j - 1] & \text{otherwise}
80+
\end{cases}
81+
$$
82+
83+
最终的答案即为 $f[m - 1][n - 1]$。
84+
85+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是网格的行数和列数。
86+
87+
我们注意到 $f[i][j]$ 仅与 $f[i - 1][j]$ 和 $f[i][j - 1]$ 有关,因此我们优化掉第一维空间,仅保留第二维空间,得到时间复杂度 $O(m \times n)$,空间复杂度 $O(n)$ 的实现。
6888

6989
<!-- tabs:start -->
7090

@@ -75,11 +95,35 @@
7595
```python
7696
class Solution:
7797
def uniquePaths(self, m: int, n: int) -> int:
78-
dp = [[1] * n for _ in range(m)]
98+
f = [[0] * n for _ in range(m)]
99+
f[0][0] = 1
100+
for i in range(m):
101+
for j in range(n):
102+
if i:
103+
f[i][j] += f[i - 1][j]
104+
if j:
105+
f[i][j] += f[i][j - 1]
106+
return f[-1][-1]
107+
```
108+
109+
```python
110+
class Solution:
111+
def uniquePaths(self, m: int, n: int) -> int:
112+
f = [[1] * n for _ in range(m)]
79113
for i in range(1, m):
80114
for j in range(1, n):
81-
dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
82-
return dp[-1][-1]
115+
f[i][j] = f[i - 1][j] + f[i][j - 1]
116+
return f[-1][-1]
117+
```
118+
119+
```python
120+
class Solution:
121+
def uniquePaths(self, m: int, n: int) -> int:
122+
f = [1] * n
123+
for _ in range(1, m):
124+
for j in range(1, n):
125+
f[j] += f[j - 1]
126+
return f[-1]
83127
```
84128

85129
### **Java**
@@ -89,31 +133,52 @@ class Solution:
89133
```java
90134
class Solution {
91135
public int uniquePaths(int m, int n) {
92-
int[][] dp = new int[m][n];
136+
var f = new int[m][n];
137+
f[0][0] = 1;
93138
for (int i = 0; i < m; ++i) {
94-
Arrays.fill(dp[i], 1);
139+
for (int j = 0; j < n; ++j) {
140+
if (i > 0) {
141+
f[i][j] += f[i - 1][j];
142+
}
143+
if (j > 0) {
144+
f[i][j] += f[i][j - 1];
145+
}
146+
}
147+
}
148+
return f[m - 1][n - 1];
149+
}
150+
}
151+
```
152+
153+
```java
154+
class Solution {
155+
public int uniquePaths(int m, int n) {
156+
var f = new int[m][n];
157+
for (var g : f) {
158+
Arrays.fill(g, 1);
95159
}
96160
for (int i = 1; i < m; ++i) {
97-
for (int j = 1; j < n; ++j) {
98-
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
161+
for (int j = 1; j < n; j++) {
162+
f[i][j] = f[i - 1][j] + f[i][j - 1];
99163
}
100164
}
101-
return dp[m - 1][n - 1];
165+
return f[m - 1][n - 1];
102166
}
103167
}
104168
```
105169

106-
### **TypeScript**
107-
108-
```ts
109-
function uniquePaths(m: number, n: number): number {
110-
let dp = Array.from({ length: m }, v => new Array(n).fill(1));
111-
for (let i = 1; i < m; ++i) {
112-
for (let j = 1; j < n; ++j) {
113-
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
170+
```java
171+
class Solution {
172+
public int uniquePaths(int m, int n) {
173+
int[] f = new int[n];
174+
Arrays.fill(f, 1);
175+
for (int i = 1; i < m; ++i) {
176+
for (int j = 1; j < n; ++j) {
177+
f[j] += f[j - 1];
178+
}
114179
}
180+
return f[n - 1];
115181
}
116-
return dp[m - 1][n - 1];
117182
}
118183
```
119184

@@ -123,13 +188,49 @@ function uniquePaths(m: number, n: number): number {
123188
class Solution {
124189
public:
125190
int uniquePaths(int m, int n) {
126-
vector<vector<int>> dp(m, vector<int>(n, 1));
191+
vector<vector<int>> f(m, vector<int>(n));
192+
f[0][0] = 1;
193+
for (int i = 0; i < m; ++i) {
194+
for (int j = 0; j < n; ++j) {
195+
if (i) {
196+
f[i][j] += f[i - 1][j];
197+
}
198+
if (j) {
199+
f[i][j] += f[i][j - 1];
200+
}
201+
}
202+
}
203+
return f[m - 1][n - 1];
204+
}
205+
};
206+
```
207+
208+
```cpp
209+
class Solution {
210+
public:
211+
int uniquePaths(int m, int n) {
212+
vector<vector<int>> f(m, vector<int>(n, 1));
127213
for (int i = 1; i < m; ++i) {
128214
for (int j = 1; j < n; ++j) {
129-
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
215+
f[i][j] = f[i - 1][j] + f[i][j - 1];
130216
}
131217
}
132-
return dp[m - 1][n - 1];
218+
return f[m - 1][n - 1];
219+
}
220+
};
221+
```
222+
223+
```cpp
224+
class Solution {
225+
public:
226+
int uniquePaths(int m, int n) {
227+
vector<int> f(n, 1);
228+
for (int i = 1; i < m; ++i) {
229+
for (int j = 1; j < n; ++j) {
230+
f[j] += f[j - 1];
231+
}
232+
}
233+
return f[n - 1];
133234
}
134235
};
135236
```
@@ -138,20 +239,183 @@ public:
138239
139240
```go
140241
func uniquePaths(m int, n int) int {
141-
dp := make([][]int, m)
142-
for i := 0; i < m; i++ {
143-
dp[i] = make([]int, n)
242+
f := make([][]int, m)
243+
for i := range f {
244+
f[i] = make([]int, n)
144245
}
246+
f[0][0] = 1
145247
for i := 0; i < m; i++ {
146248
for j := 0; j < n; j++ {
147-
if i == 0 || j == 0 {
148-
dp[i][j] = 1
149-
} else {
150-
dp[i][j] = dp[i-1][j] + dp[i][j-1]
249+
if i > 0 {
250+
f[i][j] += f[i-1][j]
251+
}
252+
if j > 0 {
253+
f[i][j] += f[i][j-1]
151254
}
152255
}
153256
}
154-
return dp[m-1][n-1]
257+
return f[m-1][n-1]
258+
}
259+
```
260+
261+
```go
262+
func uniquePaths(m int, n int) int {
263+
f := make([][]int, m)
264+
for i := range f {
265+
f[i] = make([]int, n)
266+
for j := range f[i] {
267+
f[i][j] = 1
268+
}
269+
}
270+
for i := 1; i < m; i++ {
271+
for j := 1; j < n; j++ {
272+
f[i][j] = f[i-1][j] + f[i][j-1]
273+
}
274+
}
275+
return f[m-1][n-1]
276+
}
277+
```
278+
279+
```go
280+
func uniquePaths(m int, n int) int {
281+
f := make([]int, n+1)
282+
for i := range f {
283+
f[i] = 1
284+
}
285+
for i := 1; i < m; i++ {
286+
for j := 1; j < n; j++ {
287+
f[j] += f[j-1]
288+
}
289+
}
290+
return f[n-1]
291+
}
292+
```
293+
294+
### **TypeScript**
295+
296+
```ts
297+
function uniquePaths(m: number, n: number): number {
298+
const f: number[][] = Array(m)
299+
.fill(0)
300+
.map(() => Array(n).fill(0));
301+
f[0][0] = 1;
302+
for (let i = 0; i < m; ++i) {
303+
for (let j = 0; j < n; ++j) {
304+
if (i > 0) {
305+
f[i][j] += f[i - 1][j];
306+
}
307+
if (j > 0) {
308+
f[i][j] += f[i][j - 1];
309+
}
310+
}
311+
}
312+
return f[m - 1][n - 1];
313+
}
314+
```
315+
316+
```ts
317+
function uniquePaths(m: number, n: number): number {
318+
const f: number[][] = Array(m)
319+
.fill(0)
320+
.map(() => Array(n).fill(1));
321+
for (let i = 1; i < m; ++i) {
322+
for (let j = 1; j < n; ++j) {
323+
f[i][j] = f[i - 1][j] + f[i][j - 1];
324+
}
325+
}
326+
return f[m - 1][n - 1];
327+
}
328+
```
329+
330+
```ts
331+
function uniquePaths(m: number, n: number): number {
332+
const f: number[] = Array(n).fill(1);
333+
for (let i = 1; i < m; ++i) {
334+
for (let j = 1; j < n; ++j) {
335+
f[j] += f[j - 1];
336+
}
337+
}
338+
return f[n - 1];
339+
}
340+
```
341+
342+
### **JavaScript**
343+
344+
```js
345+
/**
346+
* @param {number} m
347+
* @param {number} n
348+
* @return {number}
349+
*/
350+
var uniquePaths = function (m, n) {
351+
const f = Array(m)
352+
.fill(0)
353+
.map(() => Array(n).fill(0));
354+
f[0][0] = 1;
355+
for (let i = 0; i < m; ++i) {
356+
for (let j = 0; j < n; ++j) {
357+
if (i > 0) {
358+
f[i][j] += f[i - 1][j];
359+
}
360+
if (j > 0) {
361+
f[i][j] += f[i][j - 1];
362+
}
363+
}
364+
}
365+
return f[m - 1][n - 1];
366+
};
367+
```
368+
369+
```js
370+
/**
371+
* @param {number} m
372+
* @param {number} n
373+
* @return {number}
374+
*/
375+
var uniquePaths = function (m, n) {
376+
const f = Array(m)
377+
.fill(0)
378+
.map(() => Array(n).fill(1));
379+
for (let i = 1; i < m; ++i) {
380+
for (let j = 1; j < n; ++j) {
381+
f[i][j] = f[i - 1][j] + f[i][j - 1];
382+
}
383+
}
384+
return f[m - 1][n - 1];
385+
};
386+
```
387+
388+
```js
389+
/**
390+
* @param {number} m
391+
* @param {number} n
392+
* @return {number}
393+
*/
394+
var uniquePaths = function (m, n) {
395+
const f = Array(n).fill(1);
396+
for (let i = 1; i < m; ++i) {
397+
for (let j = 1; j < n; ++j) {
398+
f[j] += f[j - 1];
399+
}
400+
}
401+
return f[n - 1];
402+
};
403+
```
404+
405+
### **Rust**
406+
407+
```rust
408+
impl Solution {
409+
pub fn unique_paths(m: i32, n: i32) -> i32 {
410+
let (m, n) = (m as usize, n as usize);
411+
let mut f = vec![1; n];
412+
for i in 1..m {
413+
for j in 1..n {
414+
f[j] += f[j - 1];
415+
}
416+
}
417+
f[n - 1]
418+
}
155419
}
156420
```
157421

0 commit comments

Comments
 (0)