@@ -78,23 +78,25 @@ tags:
7878
7979<!-- solution:start -->
8080
81- ### 方法一:记忆化搜索
81+ ### 方法一:DFS
8282
83- 建图,然后从 ` source ` 出发,进行深度优先搜索 :
83+ 我们用一个状态数组 $\textit{state}$ 来记录每个节点的状态,其中 :
8484
85- 如果遇到了 ` destination ` ,判断此时是否还有出边,如果有出边,返回 ` false ` ,否则返回 ` true ` 。
85+ - 状态 0 表示该节点未被访问过;
86+ - 状态 1 表示该节点正在被访问;
87+ - 状态 2 表示该节点已经被访问过且可以通向终点。
8688
87- 如果遇到了环(此前访问过),或者遇到了没有出边的节点,直接返回 ` false ` 。
89+ 我们首先将图构建为邻接表的形式,然后从起点出发进行深度优先搜索(DFS)。在 DFS 过程中:
8890
89- 否则,我们把当前节点标记为已访问,然后对当前节点的所有出边进行深度优先搜索,只要有一条路径无法可以到达 ` destination ` ,就返回 ` false ` ,否则返回 ` true ` 。
91+ - 如果当前节点的状态为 1,说明我们遇到了一个环,直接返回 $\text{false}$;
92+ - 如果当前节点的状态为 2,说明该节点已经被访问过且可以通向终点,直接返回 $\text{true}$;
93+ - 如果当前节点没有出边,则检查该节点是否为终点,如果是则返回 $\text{true}$,否则返回 $\text{false}$;
94+ - 否则,将当前节点的状态设为 1,递归访问所有相邻节点;
95+ - 如果所有相邻节点都能通向终点,则将当前节点的状态设为 2 并返回 $\text{true}$,否则返回 $\text{false}$。
9096
91- 过程中我们用一个数组 $f$ 记录每个节点的状态,每个 $f [ i ] $ 的值有三种,分别表示:
97+ 答案为 $\text{dfs}(\text{source})$ 的结果。
9298
93- - 对于 $f[ i] = 0$,表示节点 $i$ 未被访问;
94- - 对于 $f[ i] = 1$,表示节点 $i$ 已被访问,且可以到达 ` destination ` ;
95- - 对于 $f[ i] = 2$,表示节点 $i$ 已被访问,但无法到达 ` destination ` 。
96-
97- 时间复杂度 $O(n)$。其中 $n$ 为节点数。
99+ 时间复杂度 $O(n + m)$,其中 $n$ 和 $m$ 分别为节点数和边数。空间复杂度 $O(n + m)$,用于存储图的邻接表和状态数组。
98100
99101<!-- tabs:start -->
100102
@@ -105,22 +107,26 @@ class Solution:
105107 def leadsToDestination (
106108 self , n : int , edges : List[List[int ]], source : int , destination : int
107109 ) -> bool :
108- @cache
109- def dfs ( i ) :
110- if i == destination:
111- return not g[i]
112- if i in vis or not g[i]:
113- return False
114- vis.add(i)
110+ def dfs ( i : int ) -> bool :
111+ if st[i] :
112+ return st[i] == 2
113+ if not g[i]:
114+ return i == destination
115+
116+ st[i] = 1
115117 for j in g[i]:
116118 if not dfs(j):
117119 return False
120+ st[i] = 2
118121 return True
119122
120- g = defaultdict( list )
123+ g = [[] for _ in range (n)]
121124 for a, b in edges:
122125 g[a].append(b)
123- vis = set ()
126+ if g[destination]:
127+ return False
128+
129+ st = [0 ] * n
124130 return dfs(source)
125131```
126132
@@ -129,40 +135,37 @@ class Solution:
129135``` java
130136class Solution {
131137 private List<Integer > [] g;
132- private int [] f;
133- private boolean [] vis;
134- private int k;
138+ private int [] st;
139+ private int destination;
135140
136141 public boolean leadsToDestination (int n , int [][] edges , int source , int destination ) {
137- vis = new boolean [n] ;
142+ this . destination = destination ;
138143 g = new List [n];
139- k = destination;
140- f = new int [n];
141- Arrays . setAll(g, key - > new ArrayList<> ());
142- for (var e : edges) {
144+ Arrays . setAll(g, k - > new ArrayList<> ());
145+ for (int [] e : edges) {
143146 g[e[0 ]]. add(e[1 ]);
144147 }
148+ if (! g[destination]. isEmpty()) {
149+ return false ;
150+ }
151+ st = new int [n];
145152 return dfs(source);
146153 }
147154
148155 private boolean dfs (int i ) {
149- if (i == k ) {
150- return g [i]. isEmpty() ;
156+ if (st[i] != 0 ) {
157+ return st [i] == 2 ;
151158 }
152- if (f [i] != 0 ) {
153- return f[i] == 1 ;
159+ if (g [i]. isEmpty() ) {
160+ return i == destination ;
154161 }
155- if (vis[i] || g[i]. isEmpty()) {
156- return false ;
157- }
158- vis[i] = true ;
162+ st[i] = 1 ;
159163 for (int j : g[i]) {
160164 if (! dfs(j)) {
161- f[i] = - 1 ;
162165 return false ;
163166 }
164167 }
165- f [i] = 1 ;
168+ st [i] = 2 ;
166169 return true ;
167170 }
168171}
@@ -173,34 +176,38 @@ class Solution {
173176``` cpp
174177class Solution {
175178public:
179+ vector<vector<int >> g;
180+ vector<int > st;
181+ int destination;
182+
176183 bool leadsToDestination(int n, vector<vector<int>>& edges, int source, int destination) {
177- vector<bool > vis(n);
178- vector<vector<int >> g(n);
179- vector<int > f(n);
184+ this->destination = destination;
185+ g.assign(n, {});
180186 for (auto& e : edges) {
181187 g[e[0]].push_back(e[1]);
182188 }
183- function<bool(int)> dfs = [ &] (int i) {
184- if (i == destination) {
185- return g[ i] .empty();
186- }
187- if (f[ i] ) {
188- return f[ i] == 1;
189- }
190- if (vis[ i] || g[ i] .empty()) {
189+ if (!g[destination].empty()) {
190+ return false;
191+ }
192+ st.assign(n, 0);
193+ return dfs(source);
194+ }
195+
196+ bool dfs(int i) {
197+ if (st[i] != 0) {
198+ return st[i] == 2;
199+ }
200+ if (g[i].empty()) {
201+ return i == destination;
202+ }
203+ st[i] = 1;
204+ for (int j : g[i]) {
205+ if (!dfs(j)) {
191206 return false;
192207 }
193- vis[ i] = true;
194- for (int j : g[ i] ) {
195- if (!dfs(j)) {
196- f[ i] = -1;
197- return false;
198- }
199- }
200- f[ i] = 1;
201- return true;
202- };
203- return dfs(source);
208+ }
209+ st[i] = 2;
210+ return true;
204211 }
205212};
206213```
@@ -209,37 +216,78 @@ public:
209216
210217``` go
211218func leadsToDestination (n int , edges [][]int , source int , destination int ) bool {
212- vis := make([]bool, n)
213219 g := make ([][]int , n)
214- f := make([]int, n)
215220 for _ , e := range edges {
216221 g[e[0 ]] = append (g[e[0 ]], e[1 ])
217222 }
218- var dfs func(int) bool
223+ if len (g[destination]) > 0 {
224+ return false
225+ }
226+
227+ st := make ([]int , n)
228+
229+ var dfs func (i int ) bool
219230 dfs = func (i int ) bool {
220- if i == destination {
221- return len(g[i]) == 0
222- }
223- if f[i] != 0 {
224- return f[i] == 1
231+ if st[i] != 0 {
232+ return st[i] == 2
225233 }
226- if vis[i] || len(g[i]) == 0 {
227- return false
234+ if len (g[i]) == 0 {
235+ return i == destination
228236 }
229- vis [i] = true
237+ st [i] = 1
230238 for _ , j := range g[i] {
231239 if !dfs (j) {
232- f[i] = -1
233240 return false
234241 }
235242 }
236- f [i] = 1
243+ st [i] = 2
237244 return true
238245 }
246+
239247 return dfs (source)
240248}
241249```
242250
251+ #### TypeScript
252+
253+ ``` ts
254+ function leadsToDestination(
255+ n : number ,
256+ edges : number [][],
257+ source : number ,
258+ destination : number ,
259+ ): boolean {
260+ const g: number [][] = Array .from ({ length: n }, () => []);
261+ for (const [a, b] of edges ) {
262+ g [a ].push (b );
263+ }
264+ if (g [destination ].length > 0 ) {
265+ return false ;
266+ }
267+
268+ const st: number [] = Array (n ).fill (0 );
269+
270+ const dfs = (i : number ): boolean => {
271+ if (st [i ] !== 0 ) {
272+ return st [i ] === 2 ;
273+ }
274+ if (g [i ].length === 0 ) {
275+ return i === destination ;
276+ }
277+ st [i ] = 1 ;
278+ for (const j of g [i ]) {
279+ if (! dfs (j )) {
280+ return false ;
281+ }
282+ }
283+ st [i ] = 2 ;
284+ return true ;
285+ };
286+
287+ return dfs (source );
288+ }
289+ ```
290+
243291<!-- tabs:end -->
244292
245293<!-- solution:end -->
0 commit comments