Skip to content

Commit 92e6a5c

Browse files
authoredJan 25, 2024
feat: update solutions to lc problem: No.0841,0848 (doocs#2260)
1 parent 61017ae commit 92e6a5c

File tree

10 files changed

+188
-218
lines changed

10 files changed

+188
-218
lines changed
 

‎solution/0800-0899/0841.Keys and Rooms/README.md

+57-64
Original file line numberDiff line numberDiff line change
@@ -53,19 +53,25 @@
5353

5454
## 解法
5555

56-
### 方法一
56+
### 方法一:DFS
57+
58+
我们可以使用深度优先搜索的方法遍历整张图,统计可以到达的节点个数,并利用数组 `vis` 标记当前节点是否访问过,以防止重复访问。
59+
60+
最后统计访问过的节点个数,若与节点总数相同则说明可以访问所有节点,否则说明存在无法到达的节点。
61+
62+
时间复杂度 $O(n + m)$,空间复杂度 $O(n)$,其中 $n$ 为节点个数,而 $m$ 为边的个数。
5763

5864
<!-- tabs:start -->
5965

6066
```python
6167
class Solution:
6268
def canVisitAllRooms(self, rooms: List[List[int]]) -> bool:
63-
def dfs(u):
64-
if u in vis:
69+
def dfs(i: int):
70+
if i in vis:
6571
return
66-
vis.add(u)
67-
for v in rooms[u]:
68-
dfs(v)
72+
vis.add(i)
73+
for j in rooms[i]:
74+
dfs(j)
6975

7076
vis = set()
7177
dfs(0)
@@ -74,23 +80,25 @@ class Solution:
7480

7581
```java
7682
class Solution {
77-
private List<List<Integer>> rooms;
78-
private Set<Integer> vis;
83+
private int cnt;
84+
private boolean[] vis;
85+
private List<List<Integer>> g;
7986

8087
public boolean canVisitAllRooms(List<List<Integer>> rooms) {
81-
vis = new HashSet<>();
82-
this.rooms = rooms;
88+
g = rooms;
89+
vis = new boolean[g.size()];
8390
dfs(0);
84-
return vis.size() == rooms.size();
91+
return cnt == g.size();
8592
}
8693

87-
private void dfs(int u) {
88-
if (vis.contains(u)) {
94+
private void dfs(int i) {
95+
if (vis[i]) {
8996
return;
9097
}
91-
vis.add(u);
92-
for (int v : rooms.get(u)) {
93-
dfs(v);
98+
vis[i] = true;
99+
++cnt;
100+
for (int j : g.get(i)) {
101+
dfs(j);
94102
}
95103
}
96104
}
@@ -99,55 +107,63 @@ class Solution {
99107
```cpp
100108
class Solution {
101109
public:
102-
vector<vector<int>> rooms;
103-
unordered_set<int> vis;
104-
105110
bool canVisitAllRooms(vector<vector<int>>& rooms) {
106-
vis.clear();
107-
this->rooms = rooms;
111+
int n = rooms.size();
112+
int cnt = 0;
113+
bool vis[n];
114+
memset(vis, false, sizeof(vis));
115+
function<void(int)> dfs = [&](int i) {
116+
if (vis[i]) {
117+
return;
118+
}
119+
vis[i] = true;
120+
++cnt;
121+
for (int j : rooms[i]) {
122+
dfs(j);
123+
}
124+
};
108125
dfs(0);
109-
return vis.size() == rooms.size();
110-
}
111-
112-
void dfs(int u) {
113-
if (vis.count(u)) return;
114-
vis.insert(u);
115-
for (int v : rooms[u]) dfs(v);
126+
return cnt == n;
116127
}
117128
};
118129
```
119130
120131
```go
121132
func canVisitAllRooms(rooms [][]int) bool {
122-
vis := make(map[int]bool)
123-
var dfs func(u int)
124-
dfs = func(u int) {
125-
if vis[u] {
133+
n := len(rooms)
134+
cnt := 0
135+
vis := make([]bool, n)
136+
var dfs func(int)
137+
dfs = func(i int) {
138+
if vis[i] {
126139
return
127140
}
128-
vis[u] = true
129-
for _, v := range rooms[u] {
130-
dfs(v)
141+
vis[i] = true
142+
cnt++
143+
for _, j := range rooms[i] {
144+
dfs(j)
131145
}
132146
}
133147
dfs(0)
134-
return len(vis) == len(rooms)
148+
return cnt == n
135149
}
136150
```
137151

138152
```ts
139153
function canVisitAllRooms(rooms: number[][]): boolean {
140154
const n = rooms.length;
141-
const isOpen = new Array(n).fill(false);
155+
const vis: boolean[] = Array(n).fill(false);
142156
const dfs = (i: number) => {
143-
if (isOpen[i]) {
157+
if (vis[i]) {
144158
return;
145159
}
146-
isOpen[i] = true;
147-
rooms[i].forEach(k => dfs(k));
160+
vis[i] = true;
161+
for (const j of rooms[i]) {
162+
dfs(j);
163+
}
148164
};
149165
dfs(0);
150-
return isOpen.every(v => v);
166+
return vis.every(v => v);
151167
}
152168
```
153169

@@ -172,27 +188,4 @@ impl Solution {
172188

173189
<!-- tabs:end -->
174190

175-
### 方法二
176-
177-
<!-- tabs:start -->
178-
179-
```ts
180-
function canVisitAllRooms(rooms: number[][]): boolean {
181-
const n = rooms.length;
182-
const isOpen = new Array(n).fill(false);
183-
const keys = [0];
184-
while (keys.length !== 0) {
185-
const i = keys.pop();
186-
if (isOpen[i]) {
187-
continue;
188-
}
189-
isOpen[i] = true;
190-
keys.push(...rooms[i]);
191-
}
192-
return isOpen.every(v => v);
193-
}
194-
```
195-
196-
<!-- tabs:end -->
197-
198191
<!-- end -->

‎solution/0800-0899/0841.Keys and Rooms/README_EN.md

+57-64
Original file line numberDiff line numberDiff line change
@@ -46,19 +46,25 @@ Since we were able to visit every room, we return true.
4646

4747
## Solutions
4848

49-
### Solution 1
49+
### Solution 1: Depth-First Search (DFS)
50+
51+
We can use the Depth-First Search (DFS) method to traverse the entire graph, count the number of reachable nodes, and use an array `vis` to mark whether the current node has been visited to prevent repeated visits.
52+
53+
Finally, we count the number of visited nodes. If it is the same as the total number of nodes, it means that all nodes can be visited; otherwise, there are nodes that cannot be reached.
54+
55+
The time complexity is $O(n + m)$, and the space complexity is $O(n)$, where $n$ is the number of nodes, and $m$ is the number of edges.
5056

5157
<!-- tabs:start -->
5258

5359
```python
5460
class Solution:
5561
def canVisitAllRooms(self, rooms: List[List[int]]) -> bool:
56-
def dfs(u):
57-
if u in vis:
62+
def dfs(i: int):
63+
if i in vis:
5864
return
59-
vis.add(u)
60-
for v in rooms[u]:
61-
dfs(v)
65+
vis.add(i)
66+
for j in rooms[i]:
67+
dfs(j)
6268

6369
vis = set()
6470
dfs(0)
@@ -67,23 +73,25 @@ class Solution:
6773

6874
```java
6975
class Solution {
70-
private List<List<Integer>> rooms;
71-
private Set<Integer> vis;
76+
private int cnt;
77+
private boolean[] vis;
78+
private List<List<Integer>> g;
7279

7380
public boolean canVisitAllRooms(List<List<Integer>> rooms) {
74-
vis = new HashSet<>();
75-
this.rooms = rooms;
81+
g = rooms;
82+
vis = new boolean[g.size()];
7683
dfs(0);
77-
return vis.size() == rooms.size();
84+
return cnt == g.size();
7885
}
7986

80-
private void dfs(int u) {
81-
if (vis.contains(u)) {
87+
private void dfs(int i) {
88+
if (vis[i]) {
8289
return;
8390
}
84-
vis.add(u);
85-
for (int v : rooms.get(u)) {
86-
dfs(v);
91+
vis[i] = true;
92+
++cnt;
93+
for (int j : g.get(i)) {
94+
dfs(j);
8795
}
8896
}
8997
}
@@ -92,55 +100,63 @@ class Solution {
92100
```cpp
93101
class Solution {
94102
public:
95-
vector<vector<int>> rooms;
96-
unordered_set<int> vis;
97-
98103
bool canVisitAllRooms(vector<vector<int>>& rooms) {
99-
vis.clear();
100-
this->rooms = rooms;
104+
int n = rooms.size();
105+
int cnt = 0;
106+
bool vis[n];
107+
memset(vis, false, sizeof(vis));
108+
function<void(int)> dfs = [&](int i) {
109+
if (vis[i]) {
110+
return;
111+
}
112+
vis[i] = true;
113+
++cnt;
114+
for (int j : rooms[i]) {
115+
dfs(j);
116+
}
117+
};
101118
dfs(0);
102-
return vis.size() == rooms.size();
103-
}
104-
105-
void dfs(int u) {
106-
if (vis.count(u)) return;
107-
vis.insert(u);
108-
for (int v : rooms[u]) dfs(v);
119+
return cnt == n;
109120
}
110121
};
111122
```
112123
113124
```go
114125
func canVisitAllRooms(rooms [][]int) bool {
115-
vis := make(map[int]bool)
116-
var dfs func(u int)
117-
dfs = func(u int) {
118-
if vis[u] {
126+
n := len(rooms)
127+
cnt := 0
128+
vis := make([]bool, n)
129+
var dfs func(int)
130+
dfs = func(i int) {
131+
if vis[i] {
119132
return
120133
}
121-
vis[u] = true
122-
for _, v := range rooms[u] {
123-
dfs(v)
134+
vis[i] = true
135+
cnt++
136+
for _, j := range rooms[i] {
137+
dfs(j)
124138
}
125139
}
126140
dfs(0)
127-
return len(vis) == len(rooms)
141+
return cnt == n
128142
}
129143
```
130144

131145
```ts
132146
function canVisitAllRooms(rooms: number[][]): boolean {
133147
const n = rooms.length;
134-
const isOpen = new Array(n).fill(false);
148+
const vis: boolean[] = Array(n).fill(false);
135149
const dfs = (i: number) => {
136-
if (isOpen[i]) {
150+
if (vis[i]) {
137151
return;
138152
}
139-
isOpen[i] = true;
140-
rooms[i].forEach(k => dfs(k));
153+
vis[i] = true;
154+
for (const j of rooms[i]) {
155+
dfs(j);
156+
}
141157
};
142158
dfs(0);
143-
return isOpen.every(v => v);
159+
return vis.every(v => v);
144160
}
145161
```
146162

@@ -165,27 +181,4 @@ impl Solution {
165181

166182
<!-- tabs:end -->
167183

168-
### Solution 2
169-
170-
<!-- tabs:start -->
171-
172-
```ts
173-
function canVisitAllRooms(rooms: number[][]): boolean {
174-
const n = rooms.length;
175-
const isOpen = new Array(n).fill(false);
176-
const keys = [0];
177-
while (keys.length !== 0) {
178-
const i = keys.pop();
179-
if (isOpen[i]) {
180-
continue;
181-
}
182-
isOpen[i] = true;
183-
keys.push(...rooms[i]);
184-
}
185-
return isOpen.every(v => v);
186-
}
187-
```
188-
189-
<!-- tabs:end -->
190-
191184
<!-- end -->
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
class Solution {
22
public:
3-
vector<vector<int>> rooms;
4-
unordered_set<int> vis;
5-
63
bool canVisitAllRooms(vector<vector<int>>& rooms) {
7-
vis.clear();
8-
this->rooms = rooms;
4+
int n = rooms.size();
5+
int cnt = 0;
6+
bool vis[n];
7+
memset(vis, false, sizeof(vis));
8+
function<void(int)> dfs = [&](int i) {
9+
if (vis[i]) {
10+
return;
11+
}
12+
vis[i] = true;
13+
++cnt;
14+
for (int j : rooms[i]) {
15+
dfs(j);
16+
}
17+
};
918
dfs(0);
10-
return vis.size() == rooms.size();
11-
}
12-
13-
void dfs(int u) {
14-
if (vis.count(u)) return;
15-
vis.insert(u);
16-
for (int v : rooms[u]) dfs(v);
19+
return cnt == n;
1720
}
1821
};
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
func canVisitAllRooms(rooms [][]int) bool {
2-
vis := make(map[int]bool)
3-
var dfs func(u int)
4-
dfs = func(u int) {
5-
if vis[u] {
2+
n := len(rooms)
3+
cnt := 0
4+
vis := make([]bool, n)
5+
var dfs func(int)
6+
dfs = func(i int) {
7+
if vis[i] {
68
return
79
}
8-
vis[u] = true
9-
for _, v := range rooms[u] {
10-
dfs(v)
10+
vis[i] = true
11+
cnt++
12+
for _, j := range rooms[i] {
13+
dfs(j)
1114
}
1215
}
1316
dfs(0)
14-
return len(vis) == len(rooms)
17+
return cnt == n
1518
}
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
class Solution {
2-
private List<List<Integer>> rooms;
3-
private Set<Integer> vis;
2+
private int cnt;
3+
private boolean[] vis;
4+
private List<List<Integer>> g;
45

56
public boolean canVisitAllRooms(List<List<Integer>> rooms) {
6-
vis = new HashSet<>();
7-
this.rooms = rooms;
7+
g = rooms;
8+
vis = new boolean[g.size()];
89
dfs(0);
9-
return vis.size() == rooms.size();
10+
return cnt == g.size();
1011
}
1112

12-
private void dfs(int u) {
13-
if (vis.contains(u)) {
13+
private void dfs(int i) {
14+
if (vis[i]) {
1415
return;
1516
}
16-
vis.add(u);
17-
for (int v : rooms.get(u)) {
18-
dfs(v);
17+
vis[i] = true;
18+
++cnt;
19+
for (int j : g.get(i)) {
20+
dfs(j);
1921
}
2022
}
2123
}

‎solution/0800-0899/0841.Keys and Rooms/Solution.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
class Solution:
22
def canVisitAllRooms(self, rooms: List[List[int]]) -> bool:
3-
def dfs(u):
4-
if u in vis:
3+
def dfs(i: int):
4+
if i in vis:
55
return
6-
vis.add(u)
7-
for v in rooms[u]:
8-
dfs(v)
6+
vis.add(i)
7+
for j in rooms[i]:
8+
dfs(j)
99

1010
vis = set()
1111
dfs(0)
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
function canVisitAllRooms(rooms: number[][]): boolean {
22
const n = rooms.length;
3-
const isOpen = new Array(n).fill(false);
3+
const vis: boolean[] = Array(n).fill(false);
44
const dfs = (i: number) => {
5-
if (isOpen[i]) {
5+
if (vis[i]) {
66
return;
77
}
8-
isOpen[i] = true;
9-
rooms[i].forEach(k => dfs(k));
8+
vis[i] = true;
9+
for (const j of rooms[i]) {
10+
dfs(j);
11+
}
1012
};
1113
dfs(0);
12-
return isOpen.every(v => v);
14+
return vis.every(v => v);
1315
}

‎solution/0800-0899/0841.Keys and Rooms/Solution2.ts

-14
This file was deleted.

‎solution/0800-0899/0848.Shifting Letters/README.md

+12-18
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,18 @@
6161

6262
<!-- tabs:start -->
6363

64+
```python
65+
class Solution:
66+
def shiftingLetters(self, s: str, shifts: List[int]) -> str:
67+
n, t = len(s), 0
68+
s = list(s)
69+
for i in range(n - 1, -1, -1):
70+
t += shifts[i]
71+
j = (ord(s[i]) - ord('a') + t) % 26
72+
s[i] = ascii_lowercase[j]
73+
return ''.join(s)
74+
```
75+
6476
```python
6577
class Solution:
6678
def shiftingLetters(self, s: str, shifts: List[int]) -> str:
@@ -130,22 +142,4 @@ func shiftingLetters(s string, shifts []int) string {
130142

131143
<!-- tabs:end -->
132144

133-
### 方法二
134-
135-
<!-- tabs:start -->
136-
137-
```python
138-
class Solution:
139-
def shiftingLetters(self, s: str, shifts: List[int]) -> str:
140-
n, t = len(s), 0
141-
s = list(s)
142-
for i in range(n - 1, -1, -1):
143-
t += shifts[i]
144-
j = (ord(s[i]) - ord('a') + t) % 26
145-
s[i] = ascii_lowercase[j]
146-
return ''.join(s)
147-
```
148-
149-
<!-- tabs:end -->
150-
151145
<!-- end -->

‎solution/0800-0899/0848.Shifting Letters/README_EN.md

+12-18
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,18 @@ After shifting the first 3 letters of s by 9, we have &quot;rpl&quot;, the answe
5151

5252
<!-- tabs:start -->
5353

54+
```python
55+
class Solution:
56+
def shiftingLetters(self, s: str, shifts: List[int]) -> str:
57+
n, t = len(s), 0
58+
s = list(s)
59+
for i in range(n - 1, -1, -1):
60+
t += shifts[i]
61+
j = (ord(s[i]) - ord('a') + t) % 26
62+
s[i] = ascii_lowercase[j]
63+
return ''.join(s)
64+
```
65+
5466
```python
5567
class Solution:
5668
def shiftingLetters(self, s: str, shifts: List[int]) -> str:
@@ -120,22 +132,4 @@ func shiftingLetters(s string, shifts []int) string {
120132

121133
<!-- tabs:end -->
122134

123-
### Solution 2
124-
125-
<!-- tabs:start -->
126-
127-
```python
128-
class Solution:
129-
def shiftingLetters(self, s: str, shifts: List[int]) -> str:
130-
n, t = len(s), 0
131-
s = list(s)
132-
for i in range(n - 1, -1, -1):
133-
t += shifts[i]
134-
j = (ord(s[i]) - ord('a') + t) % 26
135-
s[i] = ascii_lowercase[j]
136-
return ''.join(s)
137-
```
138-
139-
<!-- tabs:end -->
140-
141135
<!-- end -->

0 commit comments

Comments
 (0)
Please sign in to comment.