持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情
一、题目描述
判断给定的链表中是否有环。如果有环则返回true,否则返回false。
数据范围:链表长度 0≤n≤100000 10000 0≤n≤10000,链表中任意节点的值满足 ∣val∣<=100000|val| <= 100000 ∣val∣<=100000
要求:空间复杂度 O(1),时间复杂度 O(n)
输入分为两部分,第一部分为链表,第二部分代表是否有环,然后将组成的head头结点传入到函数里面。-1代表无环,其它的数字代表有环,这些参数解释仅仅是为了方便读者自测调试。实际在编程时读入的是链表的头节点。例如输入{3,2,0,-4},1时,对应的链表结构如下图所示:
可以看出环的入口结点为从头结点开始的第1个结点(注:头结点为第0个结点),所以输出true。
示例1
输入: {3,2,0,-4},1
返回值:
true
示例2
输入: {1},-1
返回值:
false
二、思路分析
- 判断链表中是否有环,可以使用快慢指针,快指针和慢指针都指向头结点。
- 快指针每次向后移动两次、慢指针每次向后移动一格,如果链表有环,快指针会经过环并且追上慢指针。
- 如果快指针指向的节点与慢指针指向的节点相同、则代表快指针已经重复之前走过的路径,并且与慢指针相遇。
三、AC 代码
func hasCycle( head *ListNode ) bool {
if head == nil {
return false
}
slow,fast := head,head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
if slow == fast {
return true
}
}
return false
}
四、总结
判断链表是否有环的关键在于快慢指针是否会相遇,如果相遇则代表快指针已经重复之前走过的路径,说明该链表有环。