Skip to content

Commit 659f04c

Browse files
committed
feat: add solutions to lc problem: No.0980
No.0980.Unique Paths III
1 parent 76061c9 commit 659f04c

File tree

6 files changed

+458
-2
lines changed

6 files changed

+458
-2
lines changed

solution/0900-0999/0980.Unique Paths III/README.md

Lines changed: 165 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,186 @@
6060

6161
<!-- 这里可写通用的实现逻辑 -->
6262

63+
**方法一:回溯**
64+
65+
我们可以先遍历整个网格,找出起点 $(x, y)$,并且统计空白格的数量 $cnt$。
66+
67+
接下来,我们可以从起点开始搜索,得到所有的路径数。我们设计一个函数 $dfs(i, j, k)$ 表示从 $(i, j)$ 出发,且当前已经走过的单元格数量为 $k$ 的路径数。
68+
69+
在函数中,我们首先判断当前单元格是否为终点,如果是,则判断 $k$ 是否等于 $cnt + 1$,如果是,则说明当前路径是一条有效路径,返回 $1$,否则返回 $0$。
70+
71+
如果当前单元格不是终点,则我们枚举当前单元格的上下左右四个邻接单元格,如果邻接单元格未被访问过,则我们将该邻接单元格标记为已访问,然后继续搜索从该邻接单元格出发的路径数,搜索完成后,我们再将该邻接单元格标记为未访问。在搜索完成后,我们返回所有邻接单元格的路径数之和。
72+
73+
最后,我们返回从起点出发的路径数即可,即 $dfs(x, y, 1)$。
74+
75+
时间复杂度 $O(4^{m \times n})$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为网格的行数和列数。
76+
6377
<!-- tabs:start -->
6478

6579
### **Python3**
6680

6781
<!-- 这里可写当前语言的特殊实现逻辑 -->
6882

6983
```python
70-
84+
class Solution:
85+
def uniquePathsIII(self, grid: List[List[int]]) -> int:
86+
def dfs(i, j, k):
87+
if grid[i][j] == 2:
88+
return int(k == cnt + 1)
89+
ans = 0
90+
for a, b in pairwise(dirs):
91+
x, y = i + a, j + b
92+
if 0 <= x < m and 0 <= y < n and (x, y) not in vis and grid[x][y] != -1:
93+
vis.add((x, y))
94+
ans += dfs(x, y, k + 1)
95+
vis.remove((x, y))
96+
return ans
97+
98+
m, n = len(grid), len(grid[0])
99+
start = next((i, j) for i in range(m)
100+
for j in range(n) if grid[i][j] == 1)
101+
dirs = (-1, 0, 1, 0, -1)
102+
cnt = sum(grid[i][j] == 0 for i in range(m) for j in range(n))
103+
vis = {start}
104+
return dfs(*start, 0)
71105
```
72106

73107
### **Java**
74108

75109
<!-- 这里可写当前语言的特殊实现逻辑 -->
76110

77111
```java
112+
class Solution {
113+
private int m;
114+
private int n;
115+
private int cnt;
116+
private int[][] grid;
117+
private boolean[][] vis;
118+
119+
public int uniquePathsIII(int[][] grid) {
120+
m = grid.length;
121+
n = grid[0].length;
122+
this.grid = grid;
123+
int x = 0, y = 0;
124+
for (int i = 0; i < m; ++i) {
125+
for (int j = 0; j < n; ++j) {
126+
if (grid[i][j] == 0) {
127+
++cnt;
128+
} else if (grid[i][j] == 1) {
129+
x = i;
130+
y = j;
131+
}
132+
}
133+
}
134+
vis = new boolean[m][n];
135+
vis[x][y] = true;
136+
return dfs(x, y, 0);
137+
}
138+
139+
private int dfs(int i, int j, int k) {
140+
if (grid[i][j] == 2) {
141+
return k == cnt + 1 ? 1 : 0;
142+
}
143+
int ans = 0;
144+
int[] dirs = {-1, 0, 1, 0, -1};
145+
for (int h = 0; h < 4; ++h) {
146+
int x = i + dirs[h], y = j + dirs[h + 1];
147+
if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y] != -1) {
148+
vis[x][y] = true;
149+
ans += dfs(x, y, k + 1);
150+
vis[x][y] = false;
151+
}
152+
}
153+
return ans;
154+
}
155+
}
156+
```
157+
158+
### **C++**
159+
160+
```cpp
161+
class Solution {
162+
public:
163+
int uniquePathsIII(vector<vector<int>>& grid) {
164+
int m = grid.size(), n = grid[0].size();
165+
int cnt = 0;
166+
for (auto& row : grid) {
167+
for (auto& x : row) {
168+
cnt += x == 0;
169+
}
170+
}
171+
int dirs[5] = {-1, 0, 1, 0, -1};
172+
bool vis[m][n];
173+
memset(vis, false, sizeof vis);
174+
function<int(int, int, int)> dfs = [&](int i, int j, int k) -> int {
175+
if (grid[i][j] == 2) {
176+
return k == cnt + 1 ? 1 : 0;
177+
}
178+
int ans = 0;
179+
for (int h = 0; h < 4; ++h) {
180+
int x = i + dirs[h], y = j + dirs[h + 1];
181+
if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y] != -1) {
182+
vis[x][y] = true;
183+
ans += dfs(x, y, k + 1);
184+
vis[x][y] = false;
185+
}
186+
}
187+
return ans;
188+
};
189+
for (int i = 0; i < m; ++i) {
190+
for (int j = 0; j < n; ++j) {
191+
if (grid[i][j] == 1) {
192+
vis[i][j] = true;
193+
return dfs(i, j, 0);
194+
}
195+
}
196+
}
197+
return 0;
198+
}
199+
};
200+
```
78201
202+
### **Go**
203+
204+
```go
205+
func uniquePathsIII(grid [][]int) int {
206+
m, n := len(grid), len(grid[0])
207+
cnt := 0
208+
vis := make([][]bool, m)
209+
x, y := 0, 0
210+
for i, row := range grid {
211+
vis[i] = make([]bool, n)
212+
for j, v := range row {
213+
if v == 0 {
214+
cnt++
215+
} else if v == 1 {
216+
x, y = i, j
217+
}
218+
}
219+
}
220+
dirs := [5]int{-1, 0, 1, 0, -1}
221+
var dfs func(i, j, k int) int
222+
dfs = func(i, j, k int) int {
223+
if grid[i][j] == 2 {
224+
if k == cnt+1 {
225+
return 1
226+
}
227+
return 0
228+
}
229+
ans := 0
230+
for h := 0; h < 4; h++ {
231+
x, y := i+dirs[h], j+dirs[h+1]
232+
if x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y] != -1 {
233+
vis[x][y] = true
234+
ans += dfs(x, y, k+1)
235+
vis[x][y] = false
236+
}
237+
}
238+
return ans
239+
}
240+
vis[x][y] = true
241+
return dfs(x, y, 0)
242+
}
79243
```
80244

81245
### **...**

solution/0900-0999/0980.Unique Paths III/README_EN.md

Lines changed: 151 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,163 @@ Note that the starting and ending square can be anywhere in the grid.
6666
### **Python3**
6767

6868
```python
69-
69+
class Solution:
70+
def uniquePathsIII(self, grid: List[List[int]]) -> int:
71+
def dfs(i, j, k):
72+
if grid[i][j] == 2:
73+
return int(k == cnt + 1)
74+
ans = 0
75+
for a, b in pairwise(dirs):
76+
x, y = i + a, j + b
77+
if 0 <= x < m and 0 <= y < n and (x, y) not in vis and grid[x][y] != -1:
78+
vis.add((x, y))
79+
ans += dfs(x, y, k + 1)
80+
vis.remove((x, y))
81+
return ans
82+
83+
m, n = len(grid), len(grid[0])
84+
start = next((i, j) for i in range(m)
85+
for j in range(n) if grid[i][j] == 1)
86+
dirs = (-1, 0, 1, 0, -1)
87+
cnt = sum(grid[i][j] == 0 for i in range(m) for j in range(n))
88+
vis = {start}
89+
return dfs(*start, 0)
7090
```
7191

7292
### **Java**
7393

7494
```java
95+
class Solution {
96+
private int m;
97+
private int n;
98+
private int cnt;
99+
private int[][] grid;
100+
private boolean[][] vis;
101+
102+
public int uniquePathsIII(int[][] grid) {
103+
m = grid.length;
104+
n = grid[0].length;
105+
this.grid = grid;
106+
int x = 0, y = 0;
107+
for (int i = 0; i < m; ++i) {
108+
for (int j = 0; j < n; ++j) {
109+
if (grid[i][j] == 0) {
110+
++cnt;
111+
} else if (grid[i][j] == 1) {
112+
x = i;
113+
y = j;
114+
}
115+
}
116+
}
117+
vis = new boolean[m][n];
118+
vis[x][y] = true;
119+
return dfs(x, y, 0);
120+
}
121+
122+
private int dfs(int i, int j, int k) {
123+
if (grid[i][j] == 2) {
124+
return k == cnt + 1 ? 1 : 0;
125+
}
126+
int ans = 0;
127+
int[] dirs = {-1, 0, 1, 0, -1};
128+
for (int h = 0; h < 4; ++h) {
129+
int x = i + dirs[h], y = j + dirs[h + 1];
130+
if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y] != -1) {
131+
vis[x][y] = true;
132+
ans += dfs(x, y, k + 1);
133+
vis[x][y] = false;
134+
}
135+
}
136+
return ans;
137+
}
138+
}
139+
```
140+
141+
### **C++**
142+
143+
```cpp
144+
class Solution {
145+
public:
146+
int uniquePathsIII(vector<vector<int>>& grid) {
147+
int m = grid.size(), n = grid[0].size();
148+
int cnt = 0;
149+
for (auto& row : grid) {
150+
for (auto& x : row) {
151+
cnt += x == 0;
152+
}
153+
}
154+
int dirs[5] = {-1, 0, 1, 0, -1};
155+
bool vis[m][n];
156+
memset(vis, false, sizeof vis);
157+
function<int(int, int, int)> dfs = [&](int i, int j, int k) -> int {
158+
if (grid[i][j] == 2) {
159+
return k == cnt + 1 ? 1 : 0;
160+
}
161+
int ans = 0;
162+
for (int h = 0; h < 4; ++h) {
163+
int x = i + dirs[h], y = j + dirs[h + 1];
164+
if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y] != -1) {
165+
vis[x][y] = true;
166+
ans += dfs(x, y, k + 1);
167+
vis[x][y] = false;
168+
}
169+
}
170+
return ans;
171+
};
172+
for (int i = 0; i < m; ++i) {
173+
for (int j = 0; j < n; ++j) {
174+
if (grid[i][j] == 1) {
175+
vis[i][j] = true;
176+
return dfs(i, j, 0);
177+
}
178+
}
179+
}
180+
return 0;
181+
}
182+
};
183+
```
75184
185+
### **Go**
186+
187+
```go
188+
func uniquePathsIII(grid [][]int) int {
189+
m, n := len(grid), len(grid[0])
190+
cnt := 0
191+
vis := make([][]bool, m)
192+
x, y := 0, 0
193+
for i, row := range grid {
194+
vis[i] = make([]bool, n)
195+
for j, v := range row {
196+
if v == 0 {
197+
cnt++
198+
} else if v == 1 {
199+
x, y = i, j
200+
}
201+
}
202+
}
203+
dirs := [5]int{-1, 0, 1, 0, -1}
204+
var dfs func(i, j, k int) int
205+
dfs = func(i, j, k int) int {
206+
if grid[i][j] == 2 {
207+
if k == cnt+1 {
208+
return 1
209+
}
210+
return 0
211+
}
212+
ans := 0
213+
for h := 0; h < 4; h++ {
214+
x, y := i+dirs[h], j+dirs[h+1]
215+
if x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y] != -1 {
216+
vis[x][y] = true
217+
ans += dfs(x, y, k+1)
218+
vis[x][y] = false
219+
}
220+
}
221+
return ans
222+
}
223+
vis[x][y] = true
224+
return dfs(x, y, 0)
225+
}
76226
```
77227

78228
### **...**
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
class Solution {
2+
public:
3+
int uniquePathsIII(vector<vector<int>>& grid) {
4+
int m = grid.size(), n = grid[0].size();
5+
int cnt = 0;
6+
for (auto& row : grid) {
7+
for (auto& x : row) {
8+
cnt += x == 0;
9+
}
10+
}
11+
int dirs[5] = {-1, 0, 1, 0, -1};
12+
bool vis[m][n];
13+
memset(vis, false, sizeof vis);
14+
function<int(int, int, int)> dfs = [&](int i, int j, int k) -> int {
15+
if (grid[i][j] == 2) {
16+
return k == cnt + 1 ? 1 : 0;
17+
}
18+
int ans = 0;
19+
for (int h = 0; h < 4; ++h) {
20+
int x = i + dirs[h], y = j + dirs[h + 1];
21+
if (x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y] != -1) {
22+
vis[x][y] = true;
23+
ans += dfs(x, y, k + 1);
24+
vis[x][y] = false;
25+
}
26+
}
27+
return ans;
28+
};
29+
for (int i = 0; i < m; ++i) {
30+
for (int j = 0; j < n; ++j) {
31+
if (grid[i][j] == 1) {
32+
vis[i][j] = true;
33+
return dfs(i, j, 0);
34+
}
35+
}
36+
}
37+
return 0;
38+
}
39+
};

0 commit comments

Comments
 (0)