Skip to content

Commit 04a78ea

Browse files
authored
feat: add solutions to lc problem: No.2204 (#1994)
No.2204.Distance to a Cycle in Undirected Graph
1 parent f9d54b2 commit 04a78ea

File tree

9 files changed

+567
-5
lines changed

9 files changed

+567
-5
lines changed

solution/2200-2299/2204.Distance to a Cycle in Undirected Graph/README.md

+195-2
Original file line numberDiff line numberDiff line change
@@ -67,28 +67,221 @@
6767

6868
<!-- 这里可写通用的实现逻辑 -->
6969

70+
**方法一:拓扑排序**
71+
72+
我们可以先将 $edges$ 中的边转换成邻接表 $g$,其中 $g[i]$ 表示节点 $i$ 的所有邻接节点,用集合表示。
73+
74+
接下来,我们由外向内,逐层删除节点,直到最终只剩下一个环。具体做法如下:
75+
76+
我们先找出所有度为 $1$ 的节点,将这些节点从图中删除,如果删除后,其邻接节点的度变为 $1$,则将其加入队列 $q$ 中。过程中,我们按顺序记录下所有被删除的节点,记为 $seq$;并且,我们用一个数组 $f$ 记录每个节点相邻的且更接近环的节点,即 $f[i]$ 表示节点 $i$ 的相邻且更接近环的节点。
77+
78+
最后,我们初始化一个长度为 $n$ 的答案数组 $ans$,其中 $ans[i]$ 表示节点 $i$ 到环中任意节点的最小距离,初始时 $ans[i] = 0$。然后,我们从 $seq$ 的末尾开始遍历,对于每个节点 $i$,我们可以由它的相邻节点 $f[i]$ 得到 $ans[i]$ 的值,即 $ans[i] = ans[f[i]] + 1$。
79+
80+
遍历结束后,返回答案数组 $ans$ 即可。
81+
82+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为节点数。
83+
84+
相似题目:
85+
86+
- [2603. 收集树中金币](/solution/2600-2699/2603.Collect%20Coins%20in%20a%20Tree/README.md)
87+
7088
<!-- tabs:start -->
7189

7290
### **Python3**
7391

7492
<!-- 这里可写当前语言的特殊实现逻辑 -->
7593

7694
```python
77-
95+
class Solution:
96+
def distanceToCycle(self, n: int, edges: List[List[int]]) -> List[int]:
97+
g = defaultdict(set)
98+
for a, b in edges:
99+
g[a].add(b)
100+
g[b].add(a)
101+
q = deque(i for i in range(n) if len(g[i]) == 1)
102+
f = [0] * n
103+
seq = []
104+
while q:
105+
i = q.popleft()
106+
seq.append(i)
107+
for j in g[i]:
108+
g[j].remove(i)
109+
f[i] = j
110+
if len(g[j]) == 1:
111+
q.append(j)
112+
g[i].clear()
113+
ans = [0] * n
114+
for i in seq[::-1]:
115+
ans[i] = ans[f[i]] + 1
116+
return ans
78117
```
79118

80119
### **Java**
81120

82121
<!-- 这里可写当前语言的特殊实现逻辑 -->
83122

84123
```java
124+
class Solution {
125+
public int[] distanceToCycle(int n, int[][] edges) {
126+
Set<Integer>[] g = new Set[n];
127+
Arrays.setAll(g, k -> new HashSet<>());
128+
for (var e : edges) {
129+
int a = e[0], b = e[1];
130+
g[a].add(b);
131+
g[b].add(a);
132+
}
133+
Deque<Integer> q = new ArrayDeque<>();
134+
for (int i = 0; i < n; ++i) {
135+
if (g[i].size() == 1) {
136+
q.offer(i);
137+
}
138+
}
139+
int[] f = new int[n];
140+
Deque<Integer> seq = new ArrayDeque<>();
141+
while (!q.isEmpty()) {
142+
int i = q.poll();
143+
seq.push(i);
144+
for (int j : g[i]) {
145+
g[j].remove(i);
146+
f[i] = j;
147+
if (g[j].size() == 1) {
148+
q.offer(j);
149+
}
150+
}
151+
}
152+
int[] ans = new int[n];
153+
while (!seq.isEmpty()) {
154+
int i = seq.pop();
155+
ans[i] = ans[f[i]] + 1;
156+
}
157+
return ans;
158+
}
159+
}
160+
```
161+
162+
### **C++**
85163

164+
```cpp
165+
class Solution {
166+
public:
167+
vector<int> distanceToCycle(int n, vector<vector<int>>& edges) {
168+
unordered_set<int> g[n];
169+
for (auto& e : edges) {
170+
int a = e[0], b = e[1];
171+
g[a].insert(b);
172+
g[b].insert(a);
173+
}
174+
queue<int> q;
175+
for (int i = 0; i < n; ++i) {
176+
if (g[i].size() == 1) {
177+
q.push(i);
178+
}
179+
}
180+
int f[n];
181+
int seq[n];
182+
int k = 0;
183+
while (!q.empty()) {
184+
int i = q.front();
185+
q.pop();
186+
seq[k++] = i;
187+
for (int j : g[i]) {
188+
g[j].erase(i);
189+
f[i] = j;
190+
if (g[j].size() == 1) {
191+
q.push(j);
192+
}
193+
}
194+
g[i].clear();
195+
}
196+
vector<int> ans(n);
197+
for (; k; --k) {
198+
int i = seq[k - 1];
199+
ans[i] = ans[f[i]] + 1;
200+
}
201+
return ans;
202+
}
203+
};
204+
```
205+
206+
### **Go**
207+
208+
```go
209+
func distanceToCycle(n int, edges [][]int) []int {
210+
g := make([]map[int]bool, n)
211+
for i := range g {
212+
g[i] = map[int]bool{}
213+
}
214+
for _, e := range edges {
215+
a, b := e[0], e[1]
216+
g[a][b] = true
217+
g[b][a] = true
218+
}
219+
q := []int{}
220+
for i := 0; i < n; i++ {
221+
if len(g[i]) == 1 {
222+
q = append(q, i)
223+
}
224+
}
225+
f := make([]int, n)
226+
seq := []int{}
227+
for len(q) > 0 {
228+
i := q[0]
229+
q = q[1:]
230+
seq = append(seq, i)
231+
for j := range g[i] {
232+
delete(g[j], i)
233+
f[i] = j
234+
if len(g[j]) == 1 {
235+
q = append(q, j)
236+
}
237+
}
238+
g[i] = map[int]bool{}
239+
}
240+
ans := make([]int, n)
241+
for k := len(seq) - 1; k >= 0; k-- {
242+
i := seq[k]
243+
ans[i] = ans[f[i]] + 1
244+
}
245+
return ans
246+
}
86247
```
87248

88249
### **TypeScript**
89250

90251
```ts
91-
252+
function distanceToCycle(n: number, edges: number[][]): number[] {
253+
const g: Set<number>[] = new Array(n).fill(0).map(() => new Set<number>());
254+
for (const [a, b] of edges) {
255+
g[a].add(b);
256+
g[b].add(a);
257+
}
258+
const q: number[] = [];
259+
for (let i = 0; i < n; ++i) {
260+
if (g[i].size === 1) {
261+
q.push(i);
262+
}
263+
}
264+
const f: number[] = Array(n).fill(0);
265+
const seq: number[] = [];
266+
while (q.length) {
267+
const i = q.pop()!;
268+
seq.push(i);
269+
for (const j of g[i]) {
270+
g[j].delete(i);
271+
f[i] = j;
272+
if (g[j].size === 1) {
273+
q.push(j);
274+
}
275+
}
276+
g[i].clear();
277+
}
278+
const ans: number[] = Array(n).fill(0);
279+
while (seq.length) {
280+
const i = seq.pop()!;
281+
ans[i] = ans[f[i]] + 1;
282+
}
283+
return ans;
284+
}
92285
```
93286

94287
### **...**

0 commit comments

Comments
 (0)