[Leetcode]环形链表II

[Leetcode]环形链表II

Leetcode-环形链表II

题目描述

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。

说明:不允许修改给定的链表。

进阶:
你是否可以使用 O(1) 空间解决此题?

示例 1:
在这里插入图片描述

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

示例 2:
在这里插入图片描述

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

示例 3:
在这里插入图片描述

输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。

提示:
链表中节点的数目范围在范围 [0, 104] 内
-105 <= Node.val <= 105
pos 的值为 -1 或者链表中的一个有效索引

实现代码
  • 方法一: 一个非常直观的思路是:我们遍历链表中的每个节点,并将它记录下来,一旦遇到了此前遍历过的节点,就可以判定链表中存在环。
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        dicts ={} 
        pos = head
        while pos != None:
            dicts[pos] = dicts.get(pos, 0) + 1
            if dicts[pos] == 2:
                return pos
            pos = pos.next
        return None 
  • 方法二: 快慢指针
  • 参考题解
  • 定义一个慢指针 s l o w slow slow、一个快指针 f a s t fast fast s l o w slow slow每次走一步, f a s t fast fast每次走两步,如果有环一定会相遇,此时, f a s t fast fast所走距离为 s l o w slow slow所走距离的2倍,即 f = 2 s ① f=2s ① f=2s
  • 假设链表头节点链表第一个入环的节点距离为 a ,链表环内距离为 b,那么,两指针都是先走距离 a ,然后 f a s t fast fast s l o w slow slow在环内多走 n ( 不 确 定 ) n(不确定) n()圈,然后相遇,即 f = s + n b ② f=s+nb ② f=s+nb
  • 根据①②得, s = n b s=nb s=nb f = 2 n b f=2nb f=2nb
  • 走完链表第一个入环的节点需要距离 a + n b a+nb a+nb,所以 s l o w slow slow还差 a 的距离走到,而 h e a d head head链表第一个入环的节点距离也为 a
  • 所以当两指针第一次相遇后,让 f a s t fast fast指向 h e a d head head s l o w slow slow不动,之后两指针都各走一步,当再次相遇时,即为链表第一个入环的节点
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        slow, fast = head, head
        while slow != None and fast != None:
            slow = slow.next
            fast = fast.next.next if fast.next else None

            if slow != None and fast != None and slow == fast:
                fast = head
                while slow != fast:
                    slow = slow.next
                    fast = fast.next
                return fast
        return None
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值