在Go(Golang)中检查一个给定的链表是否有循环的方法

261 阅读1分钟

概述

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

例子

上面的链表有一个循环。以下是我们可以遵循的方法

  • 有两个指针。一个是慢速指针,另一个是快速指针。这两个指针最初都指向头部节点

  • 现在将慢速指针移动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