美文网首页
如何判断单链表中存在环

如何判断单链表中存在环

作者: 追风骚年 | 来源:发表于2021-01-28 17:55 被阅读0次

    关于这个问题,网络上清一色的快慢指针的做法,但是不知道大家有没有思考过,为什么快慢指针可以?快指针一次走两格,慢指针一次走一格,那快指针可以走三格么?

    慢指针一格,快指针两格

    先看一个链表:


    1.png

    如果快慢指针路线如下:

    步数 慢指针 快指针
    1 1
    2 3
    3 5
    4 3
    5 5

    可见在第步时相遇。
    有些人肯定拉皮条,这个环长度是 4 是偶数,如果是奇数的环呢?

    2.png

    同样看快慢指针:

    步数 慢指针 快指针
    1 1
    2 3
    3 5
    4 7
    5 4
    6 6

    在第步,快慢指针还是相遇。

    慢指针一格,快指针三格

    偶数环

    1.png
    步数 慢指针 快指针
    1 1
    2 4
    3 3

    第三步相遇。

    奇数环

    2.png
    步数 慢指针 快指针
    1 1
    2 4
    3 7
    4 5
    5 3
    6 6

    这里依然会相遇。

    小结

    快慢指针查找环路问题看似非常简单,其实内部是一个数学问题,假如两个指针一个每次一格,一个每次两格。因为快指针相对于慢指针是每次多一步,所以快指针先进入环内旋转,慢指针后加入内,所以环中可以看作快指针在追赶慢指针,还是因为快指针相对于慢指针的速度是多一步,所以每次移动都会缩小他们之间的一格距离。又由于环的长度是有穷的,最终的距离为0,刚刚好就追上了。

    并且在第一次相遇的时候,快指针比慢指针刚好多走了环长度的整数倍。

    type ListNode struct {
        Val  int
        Next *ListNode
    }
    
    func hasCycle(head *ListNode) bool {
        fast, slow := head, head
        for fast != nil && slow != nil {
            if slow.Next != nil && fast.Next != nil {
                slow = slow.Next
                fast = fast.Next
            } else {
                return false // 遇到空节点则无环
            }
    
            if fast.Next != nil {
                fast = fast.Next
            } else {
                return false // 遇到空节点则无环
            }
    
            if slow == fast {
                return true // 相遇则有环
            }
        }
        return false
    }
    

    相关文章

      网友评论

          本文标题:如何判断单链表中存在环

          本文链接:https://www.haomeiwen.com/subject/pfrxtltx.html