Leetcode刷题记录——面试题 02.08. 环路检测

在这里插入图片描述

此题难度在于不适用额外空间

我们将这个问题的求解分解为一下几步:

1、进入环区段
使用快慢双指针,当二者第二次重合时,意味着我们进入了环中

2、计算环的长度
从重合位置开始,慢指针继续前进,每前进一步长度+1,直到回到重合位置
此时长度计数器即为环的长度L

3、接下来需要找环的入口
3.0、我打错了代码但是居然通过的方法
由于经过1、和2、后,我们的fast仍然位于第一次重合的位置
因此我们现在设置一个起始指针start指向头结点,然后两个指针一起走,
当重合时,返回这个节点
3.1、蠢一点但是好想的办法
从链表的头指针开始,我们对每个节点,都设置一个游标指针
令游标指针从每个节点出发,走L步,若走完后回到这个节点
则返回这个节点
3.2、快的办法
由于经过1、和2、后,我们的fast仍然位于第一次重合的位置
因此我们现在设置一个起始指针start指向头结点,并先走L步,
然后二者一起走,重合则返回节点

下面依次给出三种方法的实现

3.0 “桃花源方法”:

# 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:
        if head == None:
            return None
        #双指针先进入环
        slow = head
        fast = head
        start = 0
        while True:
            if start == 0:
                start = 1
            elif start == 1 and slow == fast:
                cur = slow
                break
            if slow.next is None or fast.next is None or fast.next.next is None:
                return None
            slow = slow.next
            fast = fast.next.next
        this = cur
        cur = cur.next
        length = 1
        while cur != this:
            cur = cur.next
            length += 1
        
        start = head
        while start != fast:
            print(start.val)
            print(fast.val)
            start = start.next
            fast = fast.next
        return start


3.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:
        if head == None:
            return None
        #双指针先进入环
        slow = head
        fast = head
        start = 0
        while True:
            if start == 0:
                start = 1
            elif start == 1 and slow == fast:
                cur = slow
                break
            if slow.next is None or fast.next is None or fast.next.next is None:
                return None
            slow = slow.next
            fast = fast.next.next
        this = cur
        cur = cur.next
        length = 1
        while cur != this:
            cur = cur.next
            length += 1
        start = head
        index = 0       
        while True:
            res = start
            for i in range(length):
                res = res.next
            if res == start:
                return res
            else:
                start = start.next


3.2 快的办法:

# 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:
        if head == None:
            return None
        #双指针先进入环
        slow = head
        fast = head
        start = 0
        while True:
            if start == 0:
                start = 1
            elif start == 1 and slow == fast:
                cur = slow
                break
            if slow.next is None or fast.next is None or fast.next.next is None:
                return None
            slow = slow.next
            fast = fast.next.next
        this = cur
        cur = cur.next
        length = 1
        while cur != this:
            cur = cur.next
            length += 1
        
        start = head
        end = start
        for i in range(length):
             end = end.next
        while start != end:
            #print(start.val)
            #print(fast.val)
            start = start.next
            end = end.next
            #fast = fast.next
        return start
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值