概述
我们的目标是确定一个给定的链表是否有一个循环。如果链表中的最后一个节点指向前面的另一个节点,那么链表中就存在一个循环。
例子

上面的链表有一个循环。以下是我们可以遵循的方法
-
有两个指针。一个是慢速指针,另一个是快速指针。这两个指针最初都指向头部节点
-
现在将慢速指针移动1个节点,将快速指针移动2个节点。
slow := slow.Next
fast := fast.Next.Next
- 如果慢指针和快指针在任何时间点都是一样的,那么这个链表就有了细胞。
程序
以下是相同的程序。
package main
import "fmt"
func main() {
first := initList()
ele4 := first.AddFront(4)
first.AddFront(3)
ele2 := first.AddFront(2)
first.AddFront(1)
//Create cycle
ele4.Next = ele2
output := hasCycle(first.Head)
fmt.Println(output)
}
type ListNode struct {
Val int
Next *ListNode
}
type SingleList struct {
Len int
Head *ListNode
}
func (s *SingleList) AddFront(num int) *ListNode {
ele := &ListNode{
Val: num,
}
if s.Head == nil {
s.Head = ele
} else {
ele.Next = s.Head
s.Head = ele
}
s.Len++
return ele
}
func initList() *SingleList {
return &SingleList{}
}
func hasCycle(head *ListNode) bool {
if head == nil || head.Next == nil {
return false
}
hasCycle := false
slow := head
fast := head
for slow != nil && fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
if slow == fast {
hasCycle = true
break
}
}
return hasCycle
}
输出
true