Python教程

环形链表-环形链表II-python

本文主要是介绍环形链表-环形链表II-python,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

leetCode第141题 环形链表

给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。

示例1:

在这里插入图片描述
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

示例2:

在这里插入图片描述
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例3:

在这里插入图片描述
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

有没有pos这个条件并不影响做题,判断链表有没有环通常都是采用Floyd算法,即双指针的形式,设立一个快指针和一个慢指针。
假如链表中存在环,那么假设两个同学在操场上跑步,两人同时起跑,一个跑得快一个跑的慢,假设两个同学都一直跑,那么快同学会超过慢同学,并且会在某个点和慢同学相遇。
设定指针的起始位置为head,设定快指针和慢指针的步长(工程上通常设置为1和2),如果有环,那么快指针和慢指针会有重合的时候。
接下来就是明确没有环的时候,当只有一个结点时,快指针的下一个结点为None;快结点的下一个结点的下一个结点为None(步长为2),也说明没有环。

## python3
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def hasCycle(self, head: [ListNode]) -> bool:
        if head == None:
            return False
        slow = head
        fast = head
        while fast.next != None and fast.next.next != None:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                return True
        return False

leetCode第142题 环形链表II

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。

示例1:

在这里插入图片描述
输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

示例2:

在这里插入图片描述
输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

示例3:

在这里插入图片描述
输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。

我们先来做一个推导,假设一共有a+b个结点,其中环有b个
f走的步数是s的两倍,则f = 2s
二者相遇的时候f比s多走几个圈,f = s + nb
由上式可得,s = nb , f = 2nb
当二者相遇后,我把s拿到最开始的地方,然后f和s的步长都变为1,如果二者再次相遇会是什么情况?
当s被拿到最开始使,s = 0,f = 2nb
二者相遇只能在圈内,假设s刚好走到圈内,那么s = a,f = a + 2nb
因为2nb是圈数的整数倍,所以刚好在圈的开头(2nb可以去掉),那么此时,s = a,f = a,两人刚好会在开头相遇,然后一起移动。
---------
结论:
用快慢指针能否相遇判断是否有环,如果二者相遇,将慢(快)指针拿到开头,二者以1为步长移动,再次相遇的一定是在环的起始位置。

## python3
class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        if head == None
            return None
        slow = head
        fast = head
        loop = False
        while fast.next != None and fast.next.next != None:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                loop = True
                break
        if loop:
            slow = head
            while slow != fast:
                fast = fast.next
                slow = slow.next
            return slow
        return None

这篇关于环形链表-环形链表II-python的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!