51
51
52
52
## 解法
53
53
54
- ### 方法一:DFS/BFS
54
+ ### 方法一:DFS
55
55
56
- 建图,利用哈希表 $vis$ 记录有哪些受限的节点,然后 $DFS$ 或者 $BFS$ 搜索整个图,记录访问过的节点数目 。
56
+ 我们首先根据给定的边构建一个邻接表 $g$,其中 $g [ i ] $ 表示与节点 $i$ 相邻的节点列表。然后我们定义一个哈希表 $vis$,用于记录受限节点或者已经访问过的节点,初始时将受限节点加入到 $vis$ 中 。
57
57
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$ 为节点数。
59
63
60
64
<!-- tabs:start -->
61
65
@@ -64,89 +68,76 @@ class Solution:
64
68
def reachableNodes (
65
69
self , n : int , edges : List[List[int ]], restricted : List[int ]
66
70
) -> 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
+
67
75
g = defaultdict(list )
68
- vis = [False ] * n
69
- for v in restricted:
70
- vis[v] = True
71
76
for a, b in edges:
72
77
g[a].append(b)
73
78
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 )
87
81
```
88
82
89
83
``` java
90
84
class Solution {
91
85
private List<Integer > [] g;
92
86
private boolean [] vis;
93
- private int ans;
94
87
95
88
public int reachableNodes (int n , int [][] edges , int [] restricted ) {
96
89
g = new List [n];
97
- Arrays . setAll(g, k - > new ArrayList<> ());
98
90
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) {
103
93
int a = e[0 ], b = e[1 ];
104
94
g[a]. add(b);
105
95
g[b]. add(a);
106
96
}
107
-
108
- ans = 0 ;
109
- dfs( 0 );
110
- return ans ;
97
+ for ( int i : restricted) {
98
+ vis[i] = true ;
99
+ }
100
+ return dfs( 0 ) ;
111
101
}
112
102
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
+ }
121
110
}
111
+ return ans;
122
112
}
123
113
}
124
114
```
125
115
126
116
``` cpp
127
117
class Solution {
128
118
public:
129
- int ans;
130
-
131
119
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);
133
122
for (auto& e : edges) {
134
123
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);
137
126
}
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);
150
141
}
151
142
};
152
143
```
@@ -182,32 +173,40 @@ func reachableNodes(n int, edges [][]int, restricted []int) int {
182
173
183
174
``` ts
184
175
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 );
191
181
}
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
+ }
200
192
}
193
+ return ans ;
201
194
};
202
- dfs (0 );
203
-
204
- return res ;
195
+ return dfs (0 );
205
196
}
206
197
```
207
198
208
199
<!-- tabs: end -->
209
200
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$ 为节点数。
211
210
212
211
<!-- tabs: start -->
213
212
@@ -216,50 +215,46 @@ class Solution:
216
215
def reachableNodes (
217
216
self , n : int , edges : List[List[int ]], restricted : List[int ]
218
217
) -> int :
219
- s = set (restricted)
220
218
g = defaultdict(list )
221
219
for a, b in edges:
222
220
g[a].append(b)
223
221
g[b].append(a)
222
+ vis = set (restricted + [0 ])
224
223
q = deque([0 ])
225
- vis = [False ] * n
226
- for v in restricted:
227
- vis[v] = True
228
224
ans = 0
229
225
while q:
230
226
i = q.popleft()
231
227
ans += 1
232
- vis[i] = True
233
228
for j in g[i]:
234
- if not vis[j] :
229
+ if j not in vis:
235
230
q.append(j)
231
+ vis.add(j)
236
232
return ans
237
233
```
238
234
239
235
``` java
240
236
class Solution {
241
237
public int reachableNodes (int n , int [][] edges , int [] restricted ) {
242
238
List<Integer > [] g = new List [n];
239
+ boolean [] vis = new boolean [n];
243
240
Arrays . setAll(g, k - > new ArrayList<> ());
244
- for (int [] e : edges) {
241
+ for (var e : edges) {
245
242
int a = e[0 ], b = e[1 ];
246
243
g[a]. add(b);
247
244
g[b]. add(a);
248
245
}
249
- boolean [] vis = new boolean [n];
250
246
for (int v : restricted) {
251
247
vis[v] = true ;
252
248
}
253
249
Deque<Integer > q = new ArrayDeque<> ();
254
250
q. offer(0 );
255
251
int ans = 0 ;
256
- while ( ! q. isEmpty()) {
252
+ for (vis[ 0 ] = true ; ! q. isEmpty(); ++ ans ) {
257
253
int i = q. pollFirst();
258
- ++ ans;
259
- vis[i] = true ;
260
254
for (int j : g[i]) {
261
255
if (! vis[j]) {
262
256
q. offer(j);
257
+ vis[j] = true ;
263
258
}
264
259
}
265
260
}
@@ -272,77 +267,78 @@ class Solution {
272
267
class Solution {
273
268
public:
274
269
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);
277
272
for (auto& e : edges) {
278
273
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;
281
279
}
282
- for (int v : restricted) vis[ v] = true;
283
280
queue<int > q{{0}};
284
281
int ans = 0;
285
- while ( !q.empty()) {
282
+ for (vis [ 0 ] = true; !q.empty(); ++ans ) {
286
283
int i = q.front();
287
284
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
+ }
292
291
}
293
292
return ans;
294
293
}
295
294
};
296
295
```
297
296
298
297
```go
299
- func reachableNodes(n int, edges [][]int, restricted []int) int {
298
+ func reachableNodes(n int, edges [][]int, restricted []int) (ans int) {
300
299
g := make([][]int, n)
301
300
vis := make([]bool, n)
302
301
for _, e := range edges {
303
302
a, b := e[0], e[1]
304
303
g[a] = append(g[a], b)
305
304
g[b] = append(g[b], a)
306
305
}
307
- for _, v := range restricted {
308
- vis[v ] = true
306
+ for _, i := range restricted {
307
+ vis[i ] = true
309
308
}
310
309
q := []int{0}
311
- ans := 0
312
- for len(q) > 0 {
310
+ for vis[0] = true; len(q) > 0; ans++ {
313
311
i := q[0]
314
312
q = q[1:]
315
- ans++
316
- vis[i] = true
317
313
for _, j := range g[i] {
318
314
if !vis[j] {
315
+ vis[j] = true
319
316
q = append(q, j)
320
317
}
321
318
}
322
319
}
323
- return ans
320
+ return
324
321
}
325
322
```
326
323
327
324
``` ts
328
325
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 }, () => [] );
331
328
for (const [a, b] of edges ) {
332
329
g [a ].push (b );
333
330
g [b ].push (a );
334
331
}
335
- for (const v of restricted ) {
336
- vis [v ] = true ;
332
+ for (const i of restricted ) {
333
+ vis [i ] = true ;
337
334
}
338
- const q = [0 ];
335
+ const q: number [] = [0 ];
339
336
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 ()! ;
344
339
for (const j of g [i ]) {
345
340
if (! vis [j ]) {
341
+ vis [j ] = true ;
346
342
q .push (j );
347
343
}
348
344
}
0 commit comments