具体来说,初始时间戳 clock}=1,首次访问一个点 x 时,记录访问这个点的时间 time}[x]=\textit{clock,然后将 clock 加一。
如果首次访问一个点,则记录当前时间 startTime}=\textit{clock,并尝试从这个点出发,看能否找到环。如果找到了一个之前访问过的点 x,且之前访问 x 的时间不早于 startTime,则说明我们找到了一个新的环,此时的环长就是前后两次访问 x 的时间差,即 clock}-\textit{time}[x]。
classSolution: deflongestCycle(self, edges: List[int]) -> int: time = [0] * len(edges) clock, ans = 1, -1 for x, t inenumerate(time): if t: continue start_time = clock while x >= 0: if time[x]: # 重复访问 if time[x] >= start_time: # 找到了一个新的环 ans = max(ans, clock - time[x]) break time[x] = clock clock += 1 x = edges[x] return ans
[sol1-Java]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
classSolution { publicintlongestCycle(int[] edges) { intn= edges.length, ans = -1; vartime=newint[n]; for (inti=0, clock = 1; i < n; ++i) { if (time[i] > 0) continue; for (intx= i, startTime = clock; x >= 0; x = edges[x]) { if (time[x] > 0) { // 重复访问 if (time[x] >= startTime) // 找到了一个新的环 ans = Math.max(ans, clock - time[x]); break; } time[x] = clock++; } } return ans; } }
[sol1-C++]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
classSolution { public: intlongestCycle(vector<int> &edges){ int n = edges.size(), time[n], ans = -1; memset(time, 0, sizeof(time)); for (int i = 0, clock = 1; i < n; ++i) { if (time[i]) continue; for (int x = i, start_time = clock; x >= 0; x = edges[x]) { if (time[x]) { // 重复访问 if (time[x] >= start_time) // 找到了一个新的环 ans = max(ans, clock - time[x]); break; } time[x] = clock++; } } return ans; } };
funclongestCycle(edges []int)int { time := make([]int, len(edges)) clock, ans := 1, -1 for x, t := range time { if t > 0 { continue } for startTime := clock; x >= 0; x = edges[x] { if time[x] > 0 { // 重复访问 if time[x] >= startTime { // 找到了一个新的环 ans = max(ans, clock-time[x]) } break } time[x] = clock clock++ } } return ans }
funcmax(a, b int)int { if b > a { return b }; return a }