Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit fa17fec

Browse files
feat: add solutions to lcci problem: No.04.01 (doocs#2534)
1 parent de0b673 commit fa17fec

File tree

12 files changed

+515
-277
lines changed

12 files changed

+515
-277
lines changed

‎lcci/04.01.Route Between Nodes/README.md‎

Lines changed: 178 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -31,52 +31,66 @@
3131

3232
### 方法一:DFS
3333

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+
3444
<!-- tabs:start -->
3545

3646
```python
3747
class Solution:
3848
def findWhetherExistsPath(
3949
self, n: int, graph: List[List[int]], start: int, target: int
4050
) -> bool:
41-
def dfs(u):
42-
if u == target:
51+
def dfs(i: int):
52+
if i == target:
4353
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()
5563
return dfs(start)
5664
```
5765

5866
```java
5967
class Solution {
68+
private List<Integer>[] g;
69+
private boolean[] vis;
70+
private int target;
71+
6072
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<>());
6277
for (int[] e : graph) {
63-
g.computeIfAbsent(e[0], k ->newArrayList<>()).add(e[1]);
78+
g[e[0]].add(e[1]);
6479
}
65-
Set<Integer> vis = new HashSet<>();
66-
vis.add(start);
67-
return dfs(start, target, g, vis);
80+
return dfs(start);
6881
}
6982

70-
private boolean dfs(int u, inttarget, Map<Integer, List<Integer>>g, Set<Integer>vis) {
71-
if (u == target) {
83+
private boolean dfs(int i) {
84+
if (i == target) {
7285
return true;
7386
}
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;
8094
}
8195
}
8296
return false;
@@ -88,44 +102,50 @@ class Solution {
88102
class Solution {
89103
public:
90104
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]);
104109
}
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);
106126
}
107127
};
108128
```
109129
110130
```go
111131
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)
113134
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])
116136
}
117-
vis := map[int]bool{start: true}
118137
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 {
121140
return true
122141
}
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
129149
}
130150
}
131151
return false
@@ -134,53 +154,84 @@ func findWhetherExistsPath(n int, graph [][]int, start int, target int) bool {
134154
}
135155
```
136156

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+
137183
<!-- tabs:end -->
138184

139185
### 方法二:BFS
140186

187+
与方法一类似,我们先根据给定的图构建一个邻接表 $g,ドル其中 $g[i]$ 表示节点 $i$ 的所有邻居节点,用一个哈希表或数组 $vis$ 记录访问过的节点,然后从节点 $start$ 开始广度优先搜索,如果搜索到节点 $target,ドル则返回 `true`,否则返回 `false`
188+
189+
时间复杂度 $(n + m),ドル空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别是节点数量和边数量。
190+
141191
<!-- tabs:start -->
142192

143193
```python
144194
class Solution:
145195
def findWhetherExistsPath(
146196
self, n: int, graph: List[List[int]], start: int, target: int
147197
) -> 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)
152201
vis = {start}
202+
q = deque([start])
153203
while q:
154-
u = q.popleft()
155-
if u == target:
204+
i = q.popleft()
205+
if i == target:
156206
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)
161211
return False
162212
```
163213

164214
```java
165215
class Solution {
166216
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];
168220
for (int[] e : graph) {
169-
g.computeIfAbsent(e[0], k ->newArrayList<>()).add(e[1]);
221+
g[e[0]].add(e[1]);
170222
}
171223
Deque<Integer> q = new ArrayDeque<>();
172224
q.offer(start);
173-
Set<Integer> vis = new HashSet<>();
174-
vis.add(start);
225+
vis[start] = true;
175226
while (!q.isEmpty()) {
176-
int u = q.poll();
177-
if (u == target) {
227+
int i = q.poll();
228+
if (i == target) {
178229
return true;
179230
}
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;
184235
}
185236
}
186237
}
@@ -193,18 +244,23 @@ class Solution {
193244
class Solution {
194245
public:
195246
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+
}
198252
queue<int> q{{start}};
199-
unordered_set<int> vis{{start}};
253+
vis[start] = true;
200254
while (!q.empty()) {
201-
int u = q.front();
202-
if (u == target) return true;
255+
int i = q.front();
203256
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;
208264
}
209265
}
210266
}
@@ -215,30 +271,60 @@ public:
215271
216272
```go
217273
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)
219276
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])
222278
}
223279
q := []int{start}
224-
vis := map[int]bool{start: true}
280+
vis[start] = true
225281
for len(q) > 0 {
226-
u := q[0]
227-
if u == target {
282+
i := q[0]
283+
q = q[1:]
284+
if i == target {
228285
return true
229286
}
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)
235291
}
236292
}
237293
}
238294
return false
239295
}
240296
```
241297

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+
242328
<!-- tabs:end -->
243329

244330
<!-- end -->

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /