Skip to content

Commit 85cd222

Browse files
committed
feat: add solutions to lcof problem: No.13
1 parent 634ac4f commit 85cd222

File tree

3 files changed

+209
-94
lines changed

3 files changed

+209
-94
lines changed

lcof/面试题13. 机器人的运动范围/README.md

Lines changed: 183 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,13 @@
2727

2828
## 解法
2929

30-
此题一大误区是:遍历所有单元格,按照公式计算是否可进入,并记录可进入的方格数量。
30+
**方法一:DFS + 哈希表**
3131

32-
因为部分方格在公式上属于可进入,但不在机器人运动范围当中,进入一方格的前提条件是能够抵达相邻方格当中
32+
由于部分单元格不可达,因此,我们不能直接枚举所有坐标点 $(i, j)$ 进行判断,而是应该从起点 $(0, 0)$ 出发,搜索所有可达的节点,记录答案
3333

34-
而后,条件限制只能从 `(0,0)` 起步,对此,只需要关注方格的下方与右方即可
34+
过程中,为了避免重复搜索同一个单元格,我们可以使用数组或哈希表记录所有访问过的节点
3535

36-
**流程**
37-
38-
1. `(0,0)` 开始。
39-
40-
2. 根据公式判断 `(i, j)` 是否可进入:
41-
42-
- 可进入,并继续往右 `(i, j + 1)` 往下 `(i + 1, j)` 重新执行流程 2。
43-
- 不可进入,退出结算。
44-
45-
3. 计算可进入区域的数量,返回即可。
46-
47-
**剪枝**
48-
49-
对于已进入的方格,需要防止多次进入,否则会导致指数级耗时。
50-
51-
在确定方格可进入后,给方格加上标记。判断一个方格可进入之前,先查看是否存在对应的标记,存在标记时及时退出。
52-
53-
记录方式不限数组与哈希表。
36+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为方格的行数和列数。
5437

5538
<!-- tabs:start -->
5639

@@ -59,23 +42,90 @@
5942
```python
6043
class Solution:
6144
def movingCount(self, m: int, n: int, k: int) -> int:
45+
def f(x):
46+
s = 0
47+
while x:
48+
s += x % 10
49+
x //= 10
50+
return s
51+
52+
def dfs(i, j):
53+
vis.add((i, j))
54+
nonlocal ans
55+
ans += 1
56+
for a, b in pairwise(dirs):
57+
x, y = i + a, j + b
58+
if 0 <= x < m and 0 <= y < n and f(x) + f(y) <= k and (x, y) not in vis:
59+
dfs(x, y)
60+
61+
vis = set()
62+
ans = 0
63+
dirs = (0, 1, 0)
64+
dfs(0, 0)
65+
return ans
66+
```
67+
68+
```python
69+
class Solution:
70+
def movingCount(self, m: int, n: int, k: int) -> int:
71+
def f(x):
72+
s = 0
73+
while x:
74+
s += x % 10
75+
x //= 10
76+
return s
77+
6278
def dfs(i, j):
63-
if (
64-
i >= m
65-
or j >= n
66-
or vis[i][j]
67-
or (i % 10 + i // 10 + j % 10 + j // 10) > k
68-
):
79+
if not (0 <= i < m) or not (0 <= j < n) or f(i) + f(j) > k or (i, j) in vis:
6980
return 0
70-
vis[i][j] = True
81+
vis.add((i, j))
7182
return 1 + dfs(i + 1, j) + dfs(i, j + 1)
7283

73-
vis = [[False] * n for _ in range(m)]
84+
vis = set()
7485
return dfs(0, 0)
7586
```
7687

7788
### **Java**
7889

90+
```java
91+
class Solution {
92+
private boolean[][] vis;
93+
private int m;
94+
private int n;
95+
private int k;
96+
private int ans;
97+
98+
public int movingCount(int m, int n, int k) {
99+
this.m = m;
100+
this.n = n;
101+
this.k = k;
102+
vis = new boolean[m][n];
103+
dfs(0, 0);
104+
return ans;
105+
}
106+
107+
private void dfs(int i, int j) {
108+
vis[i][j] = true;
109+
++ans;
110+
int[] dirs = {1, 0, 1};
111+
for (int l = 0; l < 2; ++l) {
112+
int x = i + dirs[l], y = j + dirs[l + 1];
113+
if (x >= 0 && x < m && y >= 0 && y < n && f(x) + f(y) <= k && !vis[x][y]) {
114+
dfs(x, y);
115+
}
116+
}
117+
}
118+
119+
private int f(int x) {
120+
int s = 0;
121+
for (; x > 0; x /= 10) {
122+
s += x % 10;
123+
}
124+
return s;
125+
}
126+
}
127+
```
128+
79129
```java
80130
class Solution {
81131
private boolean[][] vis;
@@ -101,30 +151,61 @@ class Solution {
101151
}
102152
```
103153

104-
### **JavaScript**
154+
### **C++**
105155

106-
```js
107-
/**
108-
* @param {number} m
109-
* @param {number} n
110-
* @param {number} k
111-
* @return {number}
112-
*/
113-
var movingCount = function (m, n, k) {
114-
const vis = new Array(m * n).fill(false);
115-
let dfs = function (i, j) {
116-
if (
117-
i >= m ||
118-
j >= n ||
119-
vis[i * n + j] ||
120-
(i % 10) + Math.floor(i / 10) + (j % 10) + Math.floor(j / 10) > k
121-
) {
122-
return 0;
123-
}
124-
vis[i * n + j] = true;
125-
return 1 + dfs(i + 1, j) + dfs(i, j + 1);
126-
};
127-
return dfs(0, 0);
156+
```cpp
157+
class Solution {
158+
public:
159+
int movingCount(int m, int n, int k) {
160+
bool vis[m][n];
161+
memset(vis, false, sizeof vis);
162+
int ans = 0;
163+
int dirs[3] = {1, 0, 1};
164+
auto f = [](int x) {
165+
int s = 0;
166+
for (; x; x /= 10) {
167+
s += x % 10;
168+
}
169+
return s;
170+
};
171+
function<void(int i, int j)> dfs = [&](int i, int j) {
172+
vis[i][j] = true;
173+
++ans;
174+
for (int l = 0; l < 2; ++l) {
175+
int x = i + dirs[l], y = j + dirs[l + 1];
176+
if (x >= 0 && x < m && y >= 0 && y < n && f(x) + f(y) <= k && !vis[x][y]) {
177+
dfs(x, y);
178+
}
179+
}
180+
};
181+
dfs(0, 0);
182+
return ans;
183+
}
184+
};
185+
```
186+
187+
```cpp
188+
class Solution {
189+
public:
190+
int movingCount(int m, int n, int k) {
191+
bool vis[m][n];
192+
memset(vis, false, sizeof vis);
193+
auto f = [](int x) {
194+
int s = 0;
195+
for (; x; x /= 10) {
196+
s += x % 10;
197+
}
198+
return s;
199+
};
200+
function<int(int i, int j)> dfs = [&](int i, int j) -> int {
201+
if (i < 0 || i >= m || j < 0 || j >= n || vis[i][j] || f(i) + f(j) > k) {
202+
return false;
203+
}
204+
vis[i][j] = true;
205+
return 1 + dfs(i + 1, j) + dfs(i, j + 1);
206+
};
207+
return dfs(0, 0);
208+
}
128209
};
129210
```
130211

@@ -148,29 +229,60 @@ func movingCount(m int, n int, k int) int {
148229
}
149230
```
150231

151-
### **C++**
232+
```go
233+
func movingCount(m int, n int, k int) (ans int) {
234+
f := func(x int) (s int) {
235+
for ; x > 0; x /= 10 {
236+
s += x % 10
237+
}
238+
return
239+
}
240+
vis := make([][]bool, m)
241+
for i := range vis {
242+
vis[i] = make([]bool, n)
243+
}
152244

153-
```cpp
154-
class Solution {
155-
public:
156-
int m;
157-
int n;
158-
int k;
159-
vector<vector<bool>> vis;
245+
dirs := [3]int{1, 0, 1}
246+
var dfs func(i, j int)
247+
dfs = func(i, j int) {
248+
vis[i][j] = true
249+
ans++
250+
for l := 0; l < 2; l++ {
251+
x, y := i+dirs[l], j+dirs[l+1]
252+
if x >= 0 && x < m && y >= 0 && y < n && f(x)+f(y) <= k && !vis[x][y] {
253+
dfs(x, y)
254+
}
255+
}
256+
}
257+
dfs(0, 0)
258+
return
259+
}
260+
```
160261

161-
int movingCount(int m, int n, int k) {
162-
this->m = m;
163-
this->n = n;
164-
this->k = k;
165-
vis.resize(m, vector<bool>(n, false));
166-
return dfs(0, 0);
167-
}
262+
### **JavaScript**
168263

169-
int dfs(int i, int j) {
170-
if (i >= m || j >= n || vis[i][j] || (i % 10 + i / 10 + j % 10 + j / 10) > k) return 0;
171-
vis[i][j] = true;
264+
```js
265+
/**
266+
* @param {number} m
267+
* @param {number} n
268+
* @param {number} k
269+
* @return {number}
270+
*/
271+
var movingCount = function (m, n, k) {
272+
const vis = new Array(m * n).fill(false);
273+
let dfs = function (i, j) {
274+
if (
275+
i >= m ||
276+
j >= n ||
277+
vis[i * n + j] ||
278+
(i % 10) + Math.floor(i / 10) + (j % 10) + Math.floor(j / 10) > k
279+
) {
280+
return 0;
281+
}
282+
vis[i * n + j] = true;
172283
return 1 + dfs(i + 1, j) + dfs(i, j + 1);
173-
}
284+
};
285+
return dfs(0, 0);
174286
};
175287
```
176288

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
class Solution {
22
public:
3-
int m;
4-
int n;
5-
int k;
6-
vector<vector<bool>> vis;
7-
83
int movingCount(int m, int n, int k) {
9-
this->m = m;
10-
this->n = n;
11-
this->k = k;
12-
vis.resize(m, vector<bool>(n, false));
4+
bool vis[m][n];
5+
memset(vis, false, sizeof vis);
6+
auto f = [](int x) {
7+
int s = 0;
8+
for (; x; x /= 10) {
9+
s += x % 10;
10+
}
11+
return s;
12+
};
13+
function<int(int i, int j)> dfs = [&](int i, int j) -> int {
14+
if (i < 0 || i >= m || j < 0 || j >= n || vis[i][j] || f(i) + f(j) > k) {
15+
return false;
16+
}
17+
vis[i][j] = true;
18+
return 1 + dfs(i + 1, j) + dfs(i, j + 1);
19+
};
1320
return dfs(0, 0);
1421
}
15-
16-
int dfs(int i, int j) {
17-
if (i >= m || j >= n || vis[i][j] || (i % 10 + i / 10 + j % 10 + j / 10) > k) return 0;
18-
vis[i][j] = true;
19-
return 1 + dfs(i + 1, j) + dfs(i, j + 1);
20-
}
2122
};
Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
class Solution:
22
def movingCount(self, m: int, n: int, k: int) -> int:
3+
def f(x):
4+
s = 0
5+
while x:
6+
s += x % 10
7+
x //= 10
8+
return s
9+
310
def dfs(i, j):
4-
if (
5-
i >= m
6-
or j >= n
7-
or vis[i][j]
8-
or (i % 10 + i // 10 + j % 10 + j // 10) > k
9-
):
11+
if not (0 <= i < m) or not (0 <= j < n) or f(i) + f(j) > k or (i, j) in vis:
1012
return 0
11-
vis[i][j] = True
13+
vis.add((i, j))
1214
return 1 + dfs(i + 1, j) + dfs(i, j + 1)
1315

14-
vis = [[False] * n for _ in range(m)]
16+
vis = set()
1517
return dfs(0, 0)

0 commit comments

Comments
 (0)