LeetCode.141 环形链表

这是我参与8月更文挑战的第5天,活动详情查看:8月更文挑战html

题目描述:

141. 环形链表 - 力扣(LeetCode) (leetcode-cn.com)算法

给定一个链表,判断链表中是否有环。markdown

若是链表中有某个节点,能够经过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,咱们使用整数 pos 来表示链表尾链接到链表中的位置(索引从 0 开始)。 若是 pos-1,则在该链表中没有环。注意:pos 不做为参数进行传递,仅仅是为了标识链表的实际状况。app

若是链表中存在环,则返回 true 。 不然,返回 falseide

进阶:oop

你能用  O ( 1 ) O(1) (即,常量)内存解决此问题吗?post

示例一

image.png

输入: head = [3,2,0,-4], pos = 1
输出: true
解释: 链表中有一个环,其尾部链接到第二个节点。
复制代码

示例二

image.png

输入: head = [1,2], pos = 0
输出: true
解释: 链表中有一个环,其尾部链接到第一个节点。
复制代码

示例三

image.png

输入: head = [1], pos = -1
输出: false
解释: 链表中没有环。
复制代码

思路分析

节点计数法

最容易的就是遍历链表了,循环访问每一个列表,存入HashSet,利用HashSet不可重复的特性,若是咱们添加节点失败,就说明这个节点以前添加过,天然就是有环的,反之无环。动画

AC代码

class Solution {
    fun hasCycle(head: ListNode?): Boolean {
        val set = mutableSetOf<ListNode>()
        var p = head
        while (null != p) {
            if (!set.add(p)) {
                return true
            }
            p = p.next
        }
        return false
    }
}
复制代码

快慢指针

要判断列表中是否有环,能够定义一个慢指针slow指向链表的头结点,快指针fast指向头结点的下一个结点。而后,慢指针slow每次向前移动一个位置,快指针fast每次向前移动两个位置。这样,若是链表中存在环,快指针就会先进入环,而后追上慢指针。ui

具体思路,可参考此题解中的动画演示:lua

AC代码

class Solution {
    fun hasCycle(head: ListNode?): Boolean {
        if (null == head || null == head?.next) {
            return false
        }
        var slow = head
        var fast = head?.next
        while (slow != fast) {
            if (null == fast || null == fast?.next) {
                return false
            }
            slow = slow?.next
            fast = fast?.next?.next
        }
        return true
    }
}
复制代码

总结

摘自官解

「Floyd 判圈算法」(又称龟兔赛跑算法)

假想「乌龟」和「兔子」在链表上移动,「兔子」跑得快,「乌龟」跑得慢。当「乌龟」和「兔子」从链表上的同一个节点开始移动时,若是该链表中没有环,那么「兔子」将一直处于「乌龟」的前方;若是该链表中有环,那么「兔子」会先于「乌龟」进入环,而且一直在环内移动。等到「乌龟」进入环时,因为「兔子」的速度快,它必定会在某个时刻与乌龟相遇,即套了「乌龟」若干圈。

咱们能够根据上述思路来解决本题。具体地,咱们定义两个指针,一快一满。慢指针每次只移动一步,而快指针每次移动两步。初始时,慢指针在位置 head,而快指针在位置 head.next。这样一来,若是在移动的过程当中,快指针反过来追上慢指针,就说明该链表为环形链表。不然快指针将到达链表尾部,该链表不为环形链表。

若是咱们知道这个算法的话,那么要求的进阶答案其实就迎刃而解了。

参考

环形链表 - 环形链表 - 力扣(LeetCode) (leetcode-cn.com)

动画演示 快慢指针 #141环形链表 - 环形链表 - 力扣(LeetCode) (leetcode-cn.com)

扩展阅读

一文搞定常见的链表问题 (欢迎交流 - 环形链表 - 力扣(LeetCode) (leetcode-cn.com)

相关文章
相关标签/搜索