Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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 _ inrange(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] *nfor_inrange(m)]
16+
vis = set()
1517
return dfs(0, 0)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /