Leetcode 141:环形链表(最详细的解法!!!)

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

进阶:
你能否不使用额外空间解决此题?

解题思路

一个最简单的做法就是将链表反转,我们看链表反转后有什么问题,关于链表反转可以看这篇Leetcode 206:反转链表(最详细解决方案!!!)。

Leetcode 141:环形链表(最详细的解法!!!)_第1张图片

首先尝试反转上面的链表

Leetcode 141:环形链表(最详细的解法!!!)_第2张图片

我们发现当反转了一圈回到3的时候不会停止,而是会继续向前反转,最后会变成下图所示。

Leetcode 141:环形链表(最详细的解法!!!)_第3张图片

我们发现又回到了起点处,所以最后只要判断返回的节点是不是head,就可以判断是不是有环。

class Solution(object):
    def reverseList(self, head):
        pre = None
        cur = head
        while cur != None:
            lat = cur.next
            cur.next = pre
            pre = cur 
            cur = lat

        return pre

    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        if head != None and head.next != None\
                and self.reverseList(head) == head:
            return True
        return False

这个问题还有一个非常棒的解法,就是使用快慢指针。我们建立两个指针,一个slow一个fast,我们令移动速度关系为 V f a s t = 2 ∗ V s l o w V_{fast}=2*V_{slow} Vfast=2Vslow,我们假设环的长度为 V s l o w ∗ t i m e V_{slow}*time Vslowtime的倍数k,如果此时slowfast都在环内的话,那么在一定时间内两者必定可以相遇(使用相对速度很好理解)。

class Solution(object):
    def hasCycle(self, head):
        """
        :type head: ListNode
        :rtype: bool
        """
        if head == None:
            return False
        
        fast, slow = head, head
        while fast.next != None and fast.next.next != None:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                return True

        return False

reference:

https://leetcode.com/problems/linked-list-cycle/discuss/44498/Just-reverse-the-list

https://leetcode.com/problems/linked-list-cycle/discuss/44489/O(1)-Space-Solution

我将该问题的其他语言版本添加到了我的GitHub Leetcode

如有问题,希望大家指出!!!

你可能感兴趣的:(Problems,leetcode解题指南)