【python实现】 141. 环形链表

给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
在这里插入图片描述
解答:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.next = None

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

总结:
思路:设置两个指针slow和fast,一个步长为1,一个步长为2进行遍历。如果有环,则slow和fast总会在某一点相遇。如果没有环,则fast会先为空,或者fast.next为空。

关于环形链表问题的总结:
1、快慢指针一直到相遇时的循环次数等于环的长度。(可推导)
Case1:一个完美的环状链表,即链表头尾相连
一个环形链表:{A,B,C,A,B,C,……}
其上存在两个指针,A指针移动速度是B指针的两倍。
A,B同时从节点1出发,所经过的节点如下:
快指针A:A->C->B->A
慢指针B:A->B->C->A
A、B指针在节点A第一次相遇,循环次数为3,而环的程度正好也为3。那这个是不是巧合呢?
首先我们要理解的是循环的次数代表的是什么。

  1. 每次循环,对于B这个慢指针来说,意味着走了一个单位长度。
  2. 而对于A来说,走了两个单位长度。
  3. 那么二者第一次相遇必然是在A走了2圈,B走了1圈的时候。
  4. 假如A的速度是B的3倍,那么二者第一次相遇是在A走了3圈,B走了1圈的时候。
  5. 同理A是B的5倍速度,相遇时A走了5圈,B走了1圈

    n. A的速度是B的n倍,相遇时A走了n圈,B走了1圈
    从上面的观察我们可以发现,无论A的速度是B的几倍,两者第一次相遇必然是在B走了1圈时。
    因为B的速度代表的是链表基本的长度单位,即从一个节点移动到下一个节点的距离。
    同时在链表中,每个节点与节点之间这个距离是不变的。
    当循环结束时,B走了1圈,正好是环的长度。而B每次移动一个单位距离,因此环的长度等于循环次数。
    Case2:不完美的环状链表,即,链表中某一中间节点与尾部相连
    在这里插入图片描述
    一个环形链表(如图所示):{D,E,A,B,C,A,B,C,……}
    其上存在两个指针,A指针移动速度是B指针的两倍。
    A,B同时从节点1出发,所经过的节点如下:
    快指针A:D->A->C->B
    慢指针B:D->E->A->B
    根据上图,我们可以计算出A、B行走的距离:
    A = d+e+a+b+c+a
    B = d+e+a
    因为A的速度是B的2倍,那么A行走的距离也因该是B的2倍:
    d+e+a+b+c+a = 2(d+e+a)
    a+b+c = d+e+a
    从上图可以看出,a+b+c正好是环的长度,而d+e+a则是B行进的距离。
    又知,每次循环B移动一个单位距离,因此在不完美的环状表中,循环次数亦是等于环的长度。
    2、快慢指针相遇点到环入口的距离 = 链表起始点到环入口的距离。(可推导)
    根据上文公式,我们可以继续推导,即:
    a+b+c = d+e+a
    b+c = d+e
    b+c是相遇点到环入口的距离
    d+e是链表起点到环入口的距离

相关问题:

  • 判断是否为环形链表
    思路:使用追赶的方法,设定两个指针slow、fast,从头指针开始,每次分别前进1步、2步。如存在环,则两者相遇;如不存在环,fast遇到NULL退出。
  • 若为环形链表,求环入口点
    思路:快慢指针相遇点到环入口的距离 = 链表起始点到环入口的距离
  • 求环的长度
    思路:记录下相遇点p,slow、fast从该点开始,再次碰撞所走过的操作数就是环的长度s
  • 判断两个链表是不是相交(思路:如果两个链表相交,那么这两个链表的尾节点一定相同。直接判断尾节点是否相同即可。这里把这道题放在环形链表,因为环形链表可以拆成Y字的两个链表。)

转载网址:https://blog.csdn.net/qq_34364995/article/details/80518191

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值