Skip to content

Commit 1a87080

Browse files
authored
feat: add solutions to lc problem: No.2368 (doocs#2377)
No.2368.Reachable Nodes With Restrictions
1 parent d2e8a47 commit 1a87080

File tree

12 files changed

+330
-354
lines changed

12 files changed

+330
-354
lines changed

solution/2300-2399/2368.Reachable Nodes With Restrictions/README.md

Lines changed: 106 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,15 @@
5151

5252
## 解法
5353

54-
### 方法一:DFS/BFS
54+
### 方法一:DFS
5555

56-
建图,利用哈希表 $vis$ 记录有哪些受限的节点,然后 $DFS$ 或者 $BFS$ 搜索整个图,记录访问过的节点数目
56+
我们首先根据给定的边构建一个邻接表 $g$,其中 $g[i]$ 表示与节点 $i$ 相邻的节点列表。然后我们定义一个哈希表 $vis$,用于记录受限节点或者已经访问过的节点,初始时将受限节点加入到 $vis$ 中
5757

58-
时间复杂度 $O(n)$,空间复杂度 $O(n)$。
58+
接下来我们定义一个深度优先搜索函数 $dfs(i)$,表示从节点 $i$ 出发,可以到达的节点数。在 $dfs(i)$ 函数中,我们首先将节点 $i$ 加入到 $vis$ 中,然后遍历节点 $i$ 的相邻节点 $j$,如果 $j$ 不在 $vis$ 中,我们递归调用 $dfs(j)$,并将返回值加到结果中。
59+
60+
最后我们返回 $dfs(0)$ 即可。
61+
62+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为节点数。
5963

6064
<!-- tabs:start -->
6165

@@ -64,89 +68,76 @@ class Solution:
6468
def reachableNodes(
6569
self, n: int, edges: List[List[int]], restricted: List[int]
6670
) -> int:
71+
def dfs(i: int) -> int:
72+
vis.add(i)
73+
return 1 + sum(j not in vis and dfs(j) for j in g[i])
74+
6775
g = defaultdict(list)
68-
vis = [False] * n
69-
for v in restricted:
70-
vis[v] = True
7176
for a, b in edges:
7277
g[a].append(b)
7378
g[b].append(a)
74-
75-
def dfs(u):
76-
nonlocal ans
77-
if vis[u]:
78-
return
79-
ans += 1
80-
vis[u] = True
81-
for v in g[u]:
82-
dfs(v)
83-
84-
ans = 0
85-
dfs(0)
86-
return ans
79+
vis = set(restricted)
80+
return dfs(0)
8781
```
8882

8983
```java
9084
class Solution {
9185
private List<Integer>[] g;
9286
private boolean[] vis;
93-
private int ans;
9487

9588
public int reachableNodes(int n, int[][] edges, int[] restricted) {
9689
g = new List[n];
97-
Arrays.setAll(g, k -> new ArrayList<>());
9890
vis = new boolean[n];
99-
for (int v : restricted) {
100-
vis[v] = true;
101-
}
102-
for (int[] e : edges) {
91+
Arrays.setAll(g, k -> new ArrayList<>());
92+
for (var e : edges) {
10393
int a = e[0], b = e[1];
10494
g[a].add(b);
10595
g[b].add(a);
10696
}
107-
108-
ans = 0;
109-
dfs(0);
110-
return ans;
97+
for (int i : restricted) {
98+
vis[i] = true;
99+
}
100+
return dfs(0);
111101
}
112102

113-
private void dfs(int u) {
114-
if (vis[u]) {
115-
return;
116-
}
117-
++ans;
118-
vis[u] = true;
119-
for (int v : g[u]) {
120-
dfs(v);
103+
private int dfs(int i) {
104+
vis[i] = true;
105+
int ans = 1;
106+
for (int j : g[i]) {
107+
if (!vis[j]) {
108+
ans += dfs(j);
109+
}
121110
}
111+
return ans;
122112
}
123113
}
124114
```
125115

126116
```cpp
127117
class Solution {
128118
public:
129-
int ans;
130-
131119
int reachableNodes(int n, vector<vector<int>>& edges, vector<int>& restricted) {
132-
vector<vector<int>> g(n);
120+
vector<int> g[n];
121+
vector<int> vis(n);
133122
for (auto& e : edges) {
134123
int a = e[0], b = e[1];
135-
g[a].push_back(b);
136-
g[b].push_back(a);
124+
g[a].emplace_back(b);
125+
g[b].emplace_back(a);
137126
}
138-
vector<bool> vis(n);
139-
for (int v : restricted) vis[v] = true;
140-
ans = 0;
141-
dfs(0, g, vis);
142-
return ans;
143-
}
144-
145-
void dfs(int u, vector<vector<int>>& g, vector<bool>& vis) {
146-
if (vis[u]) return;
147-
vis[u] = true;
148-
++ans;
149-
for (int v : g[u]) dfs(v, g, vis);
127+
for (int i : restricted) {
128+
vis[i] = true;
129+
}
130+
function<int(int)> dfs = [&](int i) {
131+
vis[i] = true;
132+
int ans = 1;
133+
for (int j : g[i]) {
134+
if (!vis[j]) {
135+
ans += dfs(j);
136+
}
137+
}
138+
return ans;
139+
};
140+
return dfs(0);
150141
}
151142
};
152143
```
@@ -182,32 +173,40 @@ func reachableNodes(n int, edges [][]int, restricted []int) int {
182173

183174
```ts
184175
function reachableNodes(n: number, edges: number[][], restricted: number[]): number {
185-
let res = 0;
186-
const vis = new Array(n).fill(false);
187-
const map = new Map<number, number[]>();
188-
for (const [start, end] of edges) {
189-
map.set(start, [...(map.get(start) ?? []), end]);
190-
map.set(end, [...(map.get(end) ?? []), start]);
176+
const vis: boolean[] = Array(n).fill(false);
177+
const g: number[][] = Array.from({ length: n }, () => []);
178+
for (const [a, b] of edges) {
179+
g[a].push(b);
180+
g[b].push(a);
191181
}
192-
const dfs = (cur: number) => {
193-
if (restricted.includes(cur) || vis[cur]) {
194-
return;
195-
}
196-
res++;
197-
vis[cur] = true;
198-
for (const item of map.get(cur) ?? []) {
199-
dfs(item);
182+
for (const i of restricted) {
183+
vis[i] = true;
184+
}
185+
const dfs = (i: number): number => {
186+
vis[i] = true;
187+
let ans = 1;
188+
for (const j of g[i]) {
189+
if (!vis[j]) {
190+
ans += dfs(j);
191+
}
200192
}
193+
return ans;
201194
};
202-
dfs(0);
203-
204-
return res;
195+
return dfs(0);
205196
}
206197
```
207198

208199
<!-- tabs:end -->
209200

210-
### 方法二
201+
### 方法二:BFS
202+
203+
与方法一类似,我们首先根据给定的边构建一个邻接表 $g$,然后定义一个哈希表 $vis$,用于记录受限节点或者已经访问过的节点,初始时将受限节点加入到 $vis$ 中。
204+
205+
接下来我们使用广度优先搜索遍历整个图,统计可以到达的节点数。我们定义一个队列 $q$,初始时将节点 $0$ 加入到 $q$ 中,并且将节点 $0$ 加入到 $vis$ 中。然后我们不断从 $q$ 中取出节点 $i$,累加答案,并将节点 $i$ 的相邻节点中未访问过的节点加入到 $q$ 中,并将这些节点加入到 $vis$ 中。
206+
207+
遍历结束后,返回答案即可。
208+
209+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为节点数。
211210

212211
<!-- tabs:start -->
213212

@@ -216,50 +215,46 @@ class Solution:
216215
def reachableNodes(
217216
self, n: int, edges: List[List[int]], restricted: List[int]
218217
) -> int:
219-
s = set(restricted)
220218
g = defaultdict(list)
221219
for a, b in edges:
222220
g[a].append(b)
223221
g[b].append(a)
222+
vis = set(restricted + [0])
224223
q = deque([0])
225-
vis = [False] * n
226-
for v in restricted:
227-
vis[v] = True
228224
ans = 0
229225
while q:
230226
i = q.popleft()
231227
ans += 1
232-
vis[i] = True
233228
for j in g[i]:
234-
if not vis[j]:
229+
if j not in vis:
235230
q.append(j)
231+
vis.add(j)
236232
return ans
237233
```
238234

239235
```java
240236
class Solution {
241237
public int reachableNodes(int n, int[][] edges, int[] restricted) {
242238
List<Integer>[] g = new List[n];
239+
boolean[] vis = new boolean[n];
243240
Arrays.setAll(g, k -> new ArrayList<>());
244-
for (int[] e : edges) {
241+
for (var e : edges) {
245242
int a = e[0], b = e[1];
246243
g[a].add(b);
247244
g[b].add(a);
248245
}
249-
boolean[] vis = new boolean[n];
250246
for (int v : restricted) {
251247
vis[v] = true;
252248
}
253249
Deque<Integer> q = new ArrayDeque<>();
254250
q.offer(0);
255251
int ans = 0;
256-
while (!q.isEmpty()) {
252+
for (vis[0] = true; !q.isEmpty(); ++ans) {
257253
int i = q.pollFirst();
258-
++ans;
259-
vis[i] = true;
260254
for (int j : g[i]) {
261255
if (!vis[j]) {
262256
q.offer(j);
257+
vis[j] = true;
263258
}
264259
}
265260
}
@@ -272,77 +267,78 @@ class Solution {
272267
class Solution {
273268
public:
274269
int reachableNodes(int n, vector<vector<int>>& edges, vector<int>& restricted) {
275-
vector<vector<int>> g(n);
276-
vector<bool> vis(n);
270+
vector<int> g[n];
271+
vector<int> vis(n);
277272
for (auto& e : edges) {
278273
int a = e[0], b = e[1];
279-
g[a].push_back(b);
280-
g[b].push_back(a);
274+
g[a].emplace_back(b);
275+
g[b].emplace_back(a);
276+
}
277+
for (int i : restricted) {
278+
vis[i] = true;
281279
}
282-
for (int v : restricted) vis[v] = true;
283280
queue<int> q{{0}};
284281
int ans = 0;
285-
while (!q.empty()) {
282+
for (vis[0] = true; !q.empty(); ++ans) {
286283
int i = q.front();
287284
q.pop();
288-
++ans;
289-
vis[i] = true;
290-
for (int j : g[i])
291-
if (!vis[j]) q.push(j);
285+
for (int j : g[i]) {
286+
if (!vis[j]) {
287+
vis[j] = true;
288+
q.push(j);
289+
}
290+
}
292291
}
293292
return ans;
294293
}
295294
};
296295
```
297296
298297
```go
299-
func reachableNodes(n int, edges [][]int, restricted []int) int {
298+
func reachableNodes(n int, edges [][]int, restricted []int) (ans int) {
300299
g := make([][]int, n)
301300
vis := make([]bool, n)
302301
for _, e := range edges {
303302
a, b := e[0], e[1]
304303
g[a] = append(g[a], b)
305304
g[b] = append(g[b], a)
306305
}
307-
for _, v := range restricted {
308-
vis[v] = true
306+
for _, i := range restricted {
307+
vis[i] = true
309308
}
310309
q := []int{0}
311-
ans := 0
312-
for len(q) > 0 {
310+
for vis[0] = true; len(q) > 0; ans++ {
313311
i := q[0]
314312
q = q[1:]
315-
ans++
316-
vis[i] = true
317313
for _, j := range g[i] {
318314
if !vis[j] {
315+
vis[j] = true
319316
q = append(q, j)
320317
}
321318
}
322319
}
323-
return ans
320+
return
324321
}
325322
```
326323

327324
```ts
328325
function reachableNodes(n: number, edges: number[][], restricted: number[]): number {
329-
const g = Array.from({ length: n }, () => []);
330-
const vis = new Array(n).fill(false);
326+
const vis: boolean[] = Array(n).fill(false);
327+
const g: number[][] = Array.from({ length: n }, () => []);
331328
for (const [a, b] of edges) {
332329
g[a].push(b);
333330
g[b].push(a);
334331
}
335-
for (const v of restricted) {
336-
vis[v] = true;
332+
for (const i of restricted) {
333+
vis[i] = true;
337334
}
338-
const q = [0];
335+
const q: number[] = [0];
339336
let ans = 0;
340-
while (q.length) {
341-
const i = q.shift();
342-
++ans;
343-
vis[i] = true;
337+
for (vis[0] = true; q.length; ++ans) {
338+
const i = q.pop()!;
344339
for (const j of g[i]) {
345340
if (!vis[j]) {
341+
vis[j] = true;
346342
q.push(j);
347343
}
348344
}

0 commit comments

Comments
 (0)