算法练习|判断链表中是否有环

152 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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时,对应的链表结构如下图所示:

图片.png

可以看出环的入口结点为从头结点开始的第1个结点(注:头结点为第0个结点),所以输出true。

示例1

输入: {3,2,0,-4},1

返回值:

true

示例2

输入: {1},-1

返回值:

false

二、思路分析

  1. 判断链表中是否有环,可以使用快慢指针,快指针和慢指针都指向头结点。
  2. 快指针每次向后移动两次、慢指针每次向后移动一格,如果链表有环,快指针会经过环并且追上慢指针。
  3. 如果快指针指向的节点与慢指针指向的节点相同、则代表快指针已经重复之前走过的路径,并且与慢指针相遇。

三、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
}

四、总结

判断链表是否有环的关键在于快慢指针是否会相遇,如果相遇则代表快指针已经重复之前走过的路径,说明该链表有环。