Skip to content

Commit fdebfee

Browse files
committed
feat: add solutions to lc problem: No.2360
No.2360.Longest Cycle in a Graph
1 parent 45cd97f commit fdebfee

File tree

7 files changed

+201
-128
lines changed

7 files changed

+201
-128
lines changed

solution/2300-2399/2360.Longest Cycle in a Graph/README.md

Lines changed: 69 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@
5252

5353
<!-- 这里可写通用的实现逻辑 -->
5454

55-
**方法一:DFS**
55+
**方法一:遍历出发点**
5656

57-
$[0, n)$ 遍历出发点,记录途经的点,如果遇到已经访问过的点,说明找到了环的入口。减去起始点到出发点的距离,就是环的长度。求最大的环长度
57+
我们可以遍历 $[0,..,n-1]$ 范围内的每个节点,如果该节点未被访问过,则从该节点出发,搜索邻边节点,直到遇到环或者遇到已经访问过的节点。如果遇到环,则更新答案
5858

59-
时间复杂度 $O(n)$。
59+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为节点数
6060

6161
相似题目:[2127. 参加会议的最多员工数](/solution/2100-2199/2127.Maximum%20Employees%20to%20Be%20Invited%20to%20a%20Meeting/README.md)
6262

@@ -75,18 +75,17 @@ class Solution:
7575
for i in range(n):
7676
if vis[i]:
7777
continue
78-
curr = i
78+
j = i
7979
cycle = []
80-
while curr != -1 and not vis[curr]:
81-
vis[curr] = True
82-
cycle.append(curr)
83-
curr = edges[curr]
84-
if curr == -1:
80+
while j != -1 and not vis[j]:
81+
vis[j] = True
82+
cycle.append(j)
83+
j = edges[j]
84+
if j == -1:
8585
continue
86-
for j, v in enumerate(cycle):
87-
if v == curr:
88-
ans = max(ans, len(cycle) - j)
89-
break
86+
m = len(cycle)
87+
k = next((k for k in range(m) if cycle[k] == j), inf)
88+
ans = max(ans, m - k)
9089
return ans
9190
```
9291

@@ -104,19 +103,18 @@ class Solution {
104103
if (vis[i]) {
105104
continue;
106105
}
107-
int curr = i;
106+
int j = i;
108107
List<Integer> cycle = new ArrayList<>();
109-
while (curr != -1 && !vis[curr]) {
110-
cycle.add(curr);
111-
vis[curr] = true;
112-
curr = edges[curr];
108+
for (; j != -1 && !vis[j]; j = edges[j]) {
109+
vis[j] = true;
110+
cycle.add(j);
113111
}
114-
if (curr == -1) {
112+
if (j == -1) {
115113
continue;
116114
}
117-
for (int j = 0; j < cycle.size(); ++j) {
118-
if (cycle.get(j) == curr) {
119-
ans = Math.max(ans, cycle.size() - j);
115+
for (int k = 0; k < cycle.size(); ++k) {
116+
if (cycle.get(k) == j) {
117+
ans = Math.max(ans, cycle.size() - k);
120118
break;
121119
}
122120
}
@@ -133,21 +131,24 @@ class Solution {
133131
public:
134132
int longestCycle(vector<int>& edges) {
135133
int n = edges.size();
136-
vector<int> vis(n);
134+
vector<bool> vis(n);
137135
int ans = -1;
138136
for (int i = 0; i < n; ++i) {
139-
if (vis[i]) continue;
140-
int curr = i;
137+
if (vis[i]) {
138+
continue;
139+
}
140+
int j = i;
141141
vector<int> cycle;
142-
while (curr != -1 && !vis[curr]) {
143-
cycle.push_back(curr);
144-
vis[curr] = true;
145-
curr = edges[curr];
142+
for (; j != -1 && !vis[j]; j = edges[j]) {
143+
vis[j] = true;
144+
cycle.push_back(j);
146145
}
147-
if (curr == -1) continue;
148-
for (int j = 0; j < cycle.size(); ++j) {
149-
if (cycle[j] == curr) {
150-
ans = max(ans, (int)cycle.size() - j);
146+
if (j == -1) {
147+
continue;
148+
}
149+
for (int k = 0; k < cycle.size(); ++k) {
150+
if (cycle[k] == j) {
151+
ans = max(ans, (int) cycle.size() - k);
151152
break;
152153
}
153154
}
@@ -161,26 +162,24 @@ public:
161162
162163
```go
163164
func longestCycle(edges []int) int {
164-
n := len(edges)
165-
vis := make([]bool, n)
165+
vis := make([]bool, len(edges))
166166
ans := -1
167167
for i := range edges {
168168
if vis[i] {
169169
continue
170170
}
171-
curr := i
171+
j := i
172172
cycle := []int{}
173-
for curr != -1 && !vis[curr] {
174-
cycle = append(cycle, curr)
175-
vis[curr] = true
176-
curr = edges[curr]
173+
for ; j != -1 && !vis[j]; j = edges[j] {
174+
vis[j] = true
175+
cycle = append(cycle, j)
177176
}
178-
if curr == -1 {
177+
if j == -1 {
179178
continue
180179
}
181-
for j, v := range cycle {
182-
if v == curr {
183-
ans = max(ans, len(cycle)-j)
180+
for k := range cycle {
181+
if cycle[k] == j {
182+
ans = max(ans, len(cycle)-k)
184183
break
185184
}
186185
}
@@ -199,7 +198,32 @@ func max(a, b int) int {
199198
### **TypeScript**
200199

201200
```ts
202-
201+
function longestCycle(edges: number[]): number {
202+
const n = edges.length;
203+
const vis = new Array(n).fill(false);
204+
let ans = -1;
205+
for (let i = 0; i < n; ++i) {
206+
if (vis[i]) {
207+
continue;
208+
}
209+
let j = i;
210+
const cycle: number[] = [];
211+
for (; j != -1 && !vis[j]; j = edges[j]) {
212+
vis[j] = true;
213+
cycle.push(j);
214+
}
215+
if (j == -1) {
216+
continue;
217+
}
218+
for (let k = 0; k < cycle.length; ++k) {
219+
if (cycle[k] == j) {
220+
ans = Math.max(ans, cycle.length - k);
221+
break;
222+
}
223+
}
224+
}
225+
return ans;
226+
}
203227
```
204228

205229
### **...**

solution/2300-2399/2360.Longest Cycle in a Graph/README_EN.md

Lines changed: 66 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -55,18 +55,17 @@ class Solution:
5555
for i in range(n):
5656
if vis[i]:
5757
continue
58-
curr = i
58+
j = i
5959
cycle = []
60-
while curr != -1 and not vis[curr]:
61-
vis[curr] = True
62-
cycle.append(curr)
63-
curr = edges[curr]
64-
if curr == -1:
60+
while j != -1 and not vis[j]:
61+
vis[j] = True
62+
cycle.append(j)
63+
j = edges[j]
64+
if j == -1:
6565
continue
66-
for j, v in enumerate(cycle):
67-
if v == curr:
68-
ans = max(ans, len(cycle) - j)
69-
break
66+
m = len(cycle)
67+
k = next((k for k in range(m) if cycle[k] == j), inf)
68+
ans = max(ans, m - k)
7069
return ans
7170
```
7271

@@ -82,19 +81,18 @@ class Solution {
8281
if (vis[i]) {
8382
continue;
8483
}
85-
int curr = i;
84+
int j = i;
8685
List<Integer> cycle = new ArrayList<>();
87-
while (curr != -1 && !vis[curr]) {
88-
cycle.add(curr);
89-
vis[curr] = true;
90-
curr = edges[curr];
86+
for (; j != -1 && !vis[j]; j = edges[j]) {
87+
vis[j] = true;
88+
cycle.add(j);
9189
}
92-
if (curr == -1) {
90+
if (j == -1) {
9391
continue;
9492
}
95-
for (int j = 0; j < cycle.size(); ++j) {
96-
if (cycle.get(j) == curr) {
97-
ans = Math.max(ans, cycle.size() - j);
93+
for (int k = 0; k < cycle.size(); ++k) {
94+
if (cycle.get(k) == j) {
95+
ans = Math.max(ans, cycle.size() - k);
9896
break;
9997
}
10098
}
@@ -111,21 +109,24 @@ class Solution {
111109
public:
112110
int longestCycle(vector<int>& edges) {
113111
int n = edges.size();
114-
vector<int> vis(n);
112+
vector<bool> vis(n);
115113
int ans = -1;
116114
for (int i = 0; i < n; ++i) {
117-
if (vis[i]) continue;
118-
int curr = i;
115+
if (vis[i]) {
116+
continue;
117+
}
118+
int j = i;
119119
vector<int> cycle;
120-
while (curr != -1 && !vis[curr]) {
121-
cycle.push_back(curr);
122-
vis[curr] = true;
123-
curr = edges[curr];
120+
for (; j != -1 && !vis[j]; j = edges[j]) {
121+
vis[j] = true;
122+
cycle.push_back(j);
124123
}
125-
if (curr == -1) continue;
126-
for (int j = 0; j < cycle.size(); ++j) {
127-
if (cycle[j] == curr) {
128-
ans = max(ans, (int)cycle.size() - j);
124+
if (j == -1) {
125+
continue;
126+
}
127+
for (int k = 0; k < cycle.size(); ++k) {
128+
if (cycle[k] == j) {
129+
ans = max(ans, (int) cycle.size() - k);
129130
break;
130131
}
131132
}
@@ -139,26 +140,24 @@ public:
139140
140141
```go
141142
func longestCycle(edges []int) int {
142-
n := len(edges)
143-
vis := make([]bool, n)
143+
vis := make([]bool, len(edges))
144144
ans := -1
145145
for i := range edges {
146146
if vis[i] {
147147
continue
148148
}
149-
curr := i
149+
j := i
150150
cycle := []int{}
151-
for curr != -1 && !vis[curr] {
152-
cycle = append(cycle, curr)
153-
vis[curr] = true
154-
curr = edges[curr]
151+
for ; j != -1 && !vis[j]; j = edges[j] {
152+
vis[j] = true
153+
cycle = append(cycle, j)
155154
}
156-
if curr == -1 {
155+
if j == -1 {
157156
continue
158157
}
159-
for j, v := range cycle {
160-
if v == curr {
161-
ans = max(ans, len(cycle)-j)
158+
for k := range cycle {
159+
if cycle[k] == j {
160+
ans = max(ans, len(cycle)-k)
162161
break
163162
}
164163
}
@@ -177,7 +176,32 @@ func max(a, b int) int {
177176
### **TypeScript**
178177

179178
```ts
180-
179+
function longestCycle(edges: number[]): number {
180+
const n = edges.length;
181+
const vis = new Array(n).fill(false);
182+
let ans = -1;
183+
for (let i = 0; i < n; ++i) {
184+
if (vis[i]) {
185+
continue;
186+
}
187+
let j = i;
188+
const cycle: number[] = [];
189+
for (; j != -1 && !vis[j]; j = edges[j]) {
190+
vis[j] = true;
191+
cycle.push(j);
192+
}
193+
if (j == -1) {
194+
continue;
195+
}
196+
for (let k = 0; k < cycle.length; ++k) {
197+
if (cycle[k] == j) {
198+
ans = Math.max(ans, cycle.length - k);
199+
break;
200+
}
201+
}
202+
}
203+
return ans;
204+
}
181205
```
182206

183207
### **...**

solution/2300-2399/2360.Longest Cycle in a Graph/Solution.cpp

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,24 @@ class Solution {
22
public:
33
int longestCycle(vector<int>& edges) {
44
int n = edges.size();
5-
vector<int> vis(n);
5+
vector<bool> vis(n);
66
int ans = -1;
77
for (int i = 0; i < n; ++i) {
8-
if (vis[i]) continue;
9-
int curr = i;
8+
if (vis[i]) {
9+
continue;
10+
}
11+
int j = i;
1012
vector<int> cycle;
11-
while (curr != -1 && !vis[curr]) {
12-
cycle.push_back(curr);
13-
vis[curr] = true;
14-
curr = edges[curr];
13+
for (; j != -1 && !vis[j]; j = edges[j]) {
14+
vis[j] = true;
15+
cycle.push_back(j);
16+
}
17+
if (j == -1) {
18+
continue;
1519
}
16-
if (curr == -1) continue;
17-
for (int j = 0; j < cycle.size(); ++j) {
18-
if (cycle[j] == curr) {
19-
ans = max(ans, (int) cycle.size() - j);
20+
for (int k = 0; k < cycle.size(); ++k) {
21+
if (cycle[k] == j) {
22+
ans = max(ans, (int) cycle.size() - k);
2023
break;
2124
}
2225
}

0 commit comments

Comments
 (0)