leetcode-142:环形链表 II

简介: leetcode-142:环形链表 II

题目

题目链接

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

为了表示给定链表中的环,我们使用整数 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
解释:链表中没有环。

解题

方法一:哈希表

# 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:
        hush = {}
        cur = head
        while cur:
            if cur in hush:
                return cur
            hush[cur]=1
            cur = cur.next
        return None

方法二:双指针(进阶:空间复杂度O(1))

此方法详细链接

首先是环内相遇

后续可以推导出z=x,让一个指针从头节点开始,另一个指针一个从第一次环内相遇开始,它们接下来第一次相遇就是环形入口节点。(具体推导见详细链接)

class Solution(object):
    def detectCycle(self, head):
        fast, slow = head, head
        while True:
            if not (fast and fast.next): return
            fast, slow = fast.next.next, slow.next
            if fast == slow: break # 这行在后面,不然开始就head==head,直接break了
        fast = head
        while fast != slow:
            fast, slow = fast.next, slow.next
        return fast

由于开始都是head,后面的循环的写法要稍微变化一下(与环形链表1有所区别)

这种写法,只能开始都是head,这样才能保证两倍关系,由于fast一开始和slow相同,所以就不能使用while fast!=slow的写法了.




如果非要类似于环形链表 1的这种写法,slow=head,fast=head.next

那么slow走的步长的2倍还要+1

image.png


也就是说当n=1(fast绕了1圈),此时x=z+1

下面就需要p1=fast.next

python解法

class ListNode:
    def __init__(self, x):
        self.val = x
        self.next = None
class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        if not head:
            return 
        slow = head
        fast = head.next
        p1=None
        while fast and fast.next:
            if slow==fast:
                p1 = fast.next  #这一步是关键
                break
            else:
                slow = slow.next
                fast = fast.next.next
        if not p1:
            return 
        p2 = head
        while p1!=p2:
            p1=p1.next
            p2=p2.next
        return  p1

c++解法

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(!head){
            return nullptr;
        }
        ListNode* slow=head;
        ListNode* fast=head;
        while(true){
            if(!(fast->next&&fast->next->next)){
                return nullptr;
            }
            slow = slow->next;
            fast = fast->next->next;
            if(slow==fast){
                break;
            }
        }
        fast=head;
        while(slow!=fast){
            slow=slow->next;
            fast=fast->next;
        }
        return slow;
    }
};

java解法

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode slow=head,fast=head;
        while(true){
            if(fast==null||fast.next==null) return null;
            slow=slow.next;
            fast=fast.next.next;
            if(slow==fast) break;
        }
        fast=head;
        while(slow!=fast){
            slow=slow.next;
            fast=fast.next;
        }
        return slow;
    }
}
相关文章
|
1天前
【移除链表元素】LeetCode第203题讲解
【移除链表元素】LeetCode第203题讲解
|
1天前
|
索引
每日一题:力扣328. 奇偶链表
每日一题:力扣328. 奇偶链表
13 4
|
1天前
leetcode代码记录(移除链表元素
leetcode代码记录(移除链表元素
10 0
【每日一题】LeetCode——反转链表
【每日一题】LeetCode——反转链表
【每日一题】LeetCode——链表的中间结点
【每日一题】LeetCode——链表的中间结点
|
1天前
|
C++
[leetcode 链表] 反转链表 vs 链表相交
[leetcode 链表] 反转链表 vs 链表相交
|
1天前
【力扣】148. 排序链表
【力扣】148. 排序链表
|
1天前
|
索引
【力扣】142. 环形链表 II
【力扣】142. 环形链表 II
|
1天前
【力扣】19. 删除链表的倒数第 N 个结点
【力扣】19. 删除链表的倒数第 N 个结点
|
1天前
|
C语言 C++ 索引
【力扣】141. 环形链表、160. 相交链表、206.反转链表、234. 回文链表
【力扣】141. 环形链表、160. 相交链表、206.反转链表、234. 回文链表