31
31
32
32
### 方法一:DFS
33
33
34
+ 我们先根据给定的图构建一个邻接表 $g$,其中 $g[ i] $ 表示节点 $i$ 的所有邻居节点,用一个哈希表或数组 $vis$ 记录访问过的节点,然后从节点 $start$ 开始深度优先搜索,如果搜索到节点 $target$,则返回 ` true ` ,否则返回 ` false ` 。
35
+
36
+ 深度优先搜索的过程如下:
37
+
38
+ 1 . 如果当前节点 $i$ 等于目标节点 $target$,返回 ` true ` ;
39
+ 2 . 如果当前节点 $i$ 已经访问过,返回 ` false ` ;
40
+ 3 . 否则,将当前节点 $i$ 标记为已访问,然后遍历节点 $i$ 的所有邻居节点 $j$,递归地搜索节点 $j$。
41
+
42
+ 时间复杂度 $(n + m)$,空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别是节点数量和边数量。
43
+
34
44
<!-- tabs:start -->
35
45
36
46
``` python
37
47
class Solution :
38
48
def findWhetherExistsPath (
39
49
self , n : int , graph : List[List[int ]], start : int , target : int
40
50
) -> bool :
41
- def dfs (u ):
42
- if u == target:
51
+ def dfs (i : int ):
52
+ if i == target:
43
53
return True
44
- for v in g[u]:
45
- if v not in vis:
46
- vis.add(v)
47
- if dfs(v):
48
- return True
49
- return False
50
-
51
- g = defaultdict(list )
52
- for u, v in graph:
53
- g[u].append(v)
54
- vis = {start}
54
+ if i in vis:
55
+ return False
56
+ vis.add(i)
57
+ return any (dfs(j) for j in g[i])
58
+
59
+ g = [[] for _ in range (n)]
60
+ for a, b in graph:
61
+ g[a].append(b)
62
+ vis = set ()
55
63
return dfs(start)
56
64
```
57
65
58
66
``` java
59
67
class Solution {
68
+ private List<Integer > [] g;
69
+ private boolean [] vis;
70
+ private int target;
71
+
60
72
public boolean findWhetherExistsPath (int n , int [][] graph , int start , int target ) {
61
- Map<Integer , List<Integer > > g = new HashMap<> ();
73
+ vis = new boolean [n];
74
+ g = new List [n];
75
+ this . target = target;
76
+ Arrays . setAll(g, k - > new ArrayList<> ());
62
77
for (int [] e : graph) {
63
- g. computeIfAbsent( e[0 ], k - > new ArrayList<> ()) . add(e[1 ]);
78
+ g[ e[0 ]] . add(e[1 ]);
64
79
}
65
- Set<Integer > vis = new HashSet<> ();
66
- vis. add(start);
67
- return dfs(start, target, g, vis);
80
+ return dfs(start);
68
81
}
69
82
70
- private boolean dfs (int u , int target , Map< Integer , List< Integer > > g , Set< Integer > vis ) {
71
- if (u == target) {
83
+ private boolean dfs (int i ) {
84
+ if (i == target) {
72
85
return true ;
73
86
}
74
- for (int v : g. getOrDefault(u, Collections . emptyList())) {
75
- if (! vis. contains(v)) {
76
- vis. add(v);
77
- if (dfs(v, target, g, vis)) {
78
- return true ;
79
- }
87
+ if (vis[i]) {
88
+ return false ;
89
+ }
90
+ vis[i] = true ;
91
+ for (int j : g[i]) {
92
+ if (dfs(j)) {
93
+ return true ;
80
94
}
81
95
}
82
96
return false ;
@@ -88,44 +102,50 @@ class Solution {
88
102
class Solution {
89
103
public:
90
104
bool findWhetherExistsPath(int n, vector<vector<int >>& graph, int start, int target) {
91
- unordered_map<int, vector<int >> g;
92
- for (auto& e : graph) g[ e[ 0]] .push_back(e[ 1] );
93
- unordered_set<int > vis{{start}};
94
- return dfs(start, target, g, vis);
95
- }
96
-
97
- bool dfs(int u, int& target, unordered_map<int, vector<int>>& g, unordered_set<int>& vis) {
98
- if (u == target) return true;
99
- for (int& v : g[u]) {
100
- if (!vis.count(v)) {
101
- vis.insert(v);
102
- if (dfs(v, target, g, vis)) return true;
103
- }
105
+ vector<int > g[ n] ;
106
+ vector<bool > vis(n);
107
+ for (auto& e : graph) {
108
+ g[ e[ 0]] .push_back(e[ 1] );
104
109
}
105
- return false ;
110
+ function<bool(int)> dfs = [ &] (int i) {
111
+ if (i == target) {
112
+ return true;
113
+ }
114
+ if (vis[ i] ) {
115
+ return false;
116
+ }
117
+ vis[ i] = true;
118
+ for (int j : g[ i] ) {
119
+ if (dfs(j)) {
120
+ return true;
121
+ }
122
+ }
123
+ return false;
124
+ };
125
+ return dfs(start);
106
126
}
107
127
};
108
128
```
109
129
110
130
```go
111
131
func findWhetherExistsPath(n int, graph [][]int, start int, target int) bool {
112
- g := map [int ][]int {}
132
+ g := make([][]int, n)
133
+ vis := make([]bool, n)
113
134
for _, e := range graph {
114
- u , v := e[0 ], e[1 ]
115
- g[u] = append (g[u], v)
135
+ g[e[0]] = append(g[e[0]], e[1])
116
136
}
117
- vis := map [int ]bool {start: true }
118
137
var dfs func(int) bool
119
- dfs = func (u int ) bool {
120
- if u == target {
138
+ dfs = func(i int) bool {
139
+ if i == target {
121
140
return true
122
141
}
123
- for _ , v := range g[u] {
124
- if !vis[v] {
125
- vis[v] = true
126
- if dfs (v) {
127
- return true
128
- }
142
+ if vis[i] {
143
+ return false
144
+ }
145
+ vis[i] = true
146
+ for _, j := range g[i] {
147
+ if dfs(j) {
148
+ return true
129
149
}
130
150
}
131
151
return false
@@ -134,53 +154,84 @@ func findWhetherExistsPath(n int, graph [][]int, start int, target int) bool {
134
154
}
135
155
```
136
156
157
+ ``` ts
158
+ function findWhetherExistsPath(
159
+ n : number ,
160
+ graph : number [][],
161
+ start : number ,
162
+ target : number ,
163
+ ): boolean {
164
+ const g: number [][] = Array .from ({ length: n }, () => []);
165
+ const vis: boolean [] = Array .from ({ length: n }, () => false );
166
+ for (const [a, b] of graph ) {
167
+ g [a ].push (b );
168
+ }
169
+ const dfs = (i : number ): boolean => {
170
+ if (i === target ) {
171
+ return true ;
172
+ }
173
+ if (vis [i ]) {
174
+ return false ;
175
+ }
176
+ vis [i ] = true ;
177
+ return g [i ].some (dfs );
178
+ };
179
+ return dfs (start );
180
+ }
181
+ ```
182
+
137
183
<!-- tabs: end -->
138
184
139
185
### 方法二:BFS
140
186
187
+ 与方法一类似,我们先根据给定的图构建一个邻接表 $g$,其中 $g[ i] $ 表示节点 $i$ 的所有邻居节点,用一个哈希表或数组 $vis$ 记录访问过的节点,然后从节点 $start$ 开始广度优先搜索,如果搜索到节点 $target$,则返回 ` true ` ,否则返回 ` false ` 。
188
+
189
+ 时间复杂度 $(n + m)$,空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别是节点数量和边数量。
190
+
141
191
<!-- tabs: start -->
142
192
143
193
``` python
144
194
class Solution :
145
195
def findWhetherExistsPath (
146
196
self , n : int , graph : List[List[int ]], start : int , target : int
147
197
) -> bool :
148
- g = defaultdict(list )
149
- for u, v in graph:
150
- g[u].append(v)
151
- q = deque([start])
198
+ g = [[] for _ in range (n)]
199
+ for a, b in graph:
200
+ g[a].append(b)
152
201
vis = {start}
202
+ q = deque([start])
153
203
while q:
154
- u = q.popleft()
155
- if u == target:
204
+ i = q.popleft()
205
+ if i == target:
156
206
return True
157
- for v in g[u ]:
158
- if v not in vis:
159
- vis.add(v )
160
- q.append(v )
207
+ for j in g[i ]:
208
+ if j not in vis:
209
+ vis.add(j )
210
+ q.append(j )
161
211
return False
162
212
```
163
213
164
214
``` java
165
215
class Solution {
166
216
public boolean findWhetherExistsPath (int n , int [][] graph , int start , int target ) {
167
- Map<Integer , List<Integer > > g = new HashMap<> ();
217
+ List<Integer > [] g = new List [n];
218
+ Arrays . setAll(g, k - > new ArrayList<> ());
219
+ boolean [] vis = new boolean [n];
168
220
for (int [] e : graph) {
169
- g. computeIfAbsent( e[0 ], k - > new ArrayList<> ()) . add(e[1 ]);
221
+ g[ e[0 ]] . add(e[1 ]);
170
222
}
171
223
Deque<Integer > q = new ArrayDeque<> ();
172
224
q. offer(start);
173
- Set<Integer > vis = new HashSet<> ();
174
- vis. add(start);
225
+ vis[start] = true ;
175
226
while (! q. isEmpty()) {
176
- int u = q. poll();
177
- if (u == target) {
227
+ int i = q. poll();
228
+ if (i == target) {
178
229
return true ;
179
230
}
180
- for (int v : g. getOrDefault(u, Collections . emptyList()) ) {
181
- if (! vis. contains(v) ) {
182
- vis . add(v );
183
- q . offer(v) ;
231
+ for (int j : g[i] ) {
232
+ if (! vis[j] ) {
233
+ q . offer(j );
234
+ vis[j] = true ;
184
235
}
185
236
}
186
237
}
@@ -193,18 +244,23 @@ class Solution {
193
244
class Solution {
194
245
public:
195
246
bool findWhetherExistsPath(int n, vector<vector<int >>& graph, int start, int target) {
196
- unordered_map<int, vector<int >> g;
197
- for (auto& e : graph) g[ e[ 0]] .push_back(e[ 1] );
247
+ vector<int > g[ n] ;
248
+ vector<bool > vis(n);
249
+ for (auto& e : graph) {
250
+ g[ e[ 0]] .push_back(e[ 1] );
251
+ }
198
252
queue<int > q{{start}};
199
- unordered_set< int > vis{{ start}} ;
253
+ vis[ start] = true ;
200
254
while (!q.empty()) {
201
- int u = q.front();
202
- if (u == target) return true;
255
+ int i = q.front();
203
256
q.pop();
204
- for (int v : g[ u] ) {
205
- if (!vis.count(v)) {
206
- vis.insert(v);
207
- q.push(v);
257
+ if (i == target) {
258
+ return true;
259
+ }
260
+ for (int j : g[ i] ) {
261
+ if (!vis[ j] ) {
262
+ q.push(j);
263
+ vis[ j] = true;
208
264
}
209
265
}
210
266
}
@@ -215,30 +271,60 @@ public:
215
271
216
272
```go
217
273
func findWhetherExistsPath(n int, graph [][]int, start int, target int) bool {
218
- g := map[int][]int{}
274
+ g := make([][]int, n)
275
+ vis := make([]bool, n)
219
276
for _, e := range graph {
220
- u, v := e[0], e[1]
221
- g[u] = append(g[u], v)
277
+ g[e[0]] = append(g[e[0]], e[1])
222
278
}
223
279
q := []int{start}
224
- vis := map[int]bool{ start: true}
280
+ vis[ start] = true
225
281
for len(q) > 0 {
226
- u := q[0]
227
- if u == target {
282
+ i := q[0]
283
+ q = q[1:]
284
+ if i == target {
228
285
return true
229
286
}
230
- q = q[1:]
231
- for _, v := range g[u] {
232
- if !vis[v] {
233
- vis[v] = true
234
- q = append(q, v)
287
+ for _, j := range g[i] {
288
+ if !vis[j] {
289
+ vis[j] = true
290
+ q = append(q, j)
235
291
}
236
292
}
237
293
}
238
294
return false
239
295
}
240
296
```
241
297
298
+ ``` ts
299
+ function findWhetherExistsPath(
300
+ n : number ,
301
+ graph : number [][],
302
+ start : number ,
303
+ target : number ,
304
+ ): boolean {
305
+ const g: number [][] = Array .from ({ length: n }, () => []);
306
+ const vis: boolean [] = Array .from ({ length: n }, () => false );
307
+ for (const [a, b] of graph ) {
308
+ g [a ].push (b );
309
+ }
310
+ const q: number [] = [start ];
311
+ vis [start ] = true ;
312
+ while (q .length > 0 ) {
313
+ const i = q .pop ()! ;
314
+ if (i === target ) {
315
+ return true ;
316
+ }
317
+ for (const j of g [i ]) {
318
+ if (! vis [j ]) {
319
+ vis [j ] = true ;
320
+ q .push (j );
321
+ }
322
+ }
323
+ }
324
+ return false ;
325
+ }
326
+ ```
327
+
242
328
<!-- tabs: end -->
243
329
244
330
<!-- end -->
0 commit comments