环形链表题

简介: 环形链表题

1.环形链表1

看题:. - 力扣(LeetCode)

2267949cdba24decbca4d0b161a1e8c6.png

思路1:哈希表

遍历所有节点,每次遍历一个节点时,判断该节点是否被访问过。

遍历所有节点,每次遍历一个节点时,判断该节点是否被访问过。

可以使用哈希表来存储所有已经访问过的节点。每次到达一个节点,如果该节点已经存在于哈希表中,则说明该链表是环形链表,否则就将该节点加入哈希表中。重复这一过程,直到我们遍历完整个链表。

思路2:快慢指针

创建两个指针,一个快指针一个慢指针,快指针一次走两步,慢指针一次走一步,如果是环形链表则两个指针会相遇,所以每走一次判断两个指针是否相等。如果不是环形链表则快指针会走到NULL。


1.1.快慢指针

看图:

d37e710be33a46639865cde66d93b0f5.png

代码实现:

bool hasCycle(struct ListNode *head) {
    struct ListNode *fast=head;
    struct ListNode *slow=head;
    while(fast&&fast->next)
    {
        fast=fast->next->next;
        slow=slow->next;
        if(fast==slow)
        {
            return true;
        }
    }
    return false;
}


2.环形链表2

看题:. - 力扣(LeetCode)

480c384bf34f4a80a9db8a1c81ee6a77.png


思路1:快慢指针

先上结论:下面是一个环形链表,node结点位是快慢指针相遇的位置结点,phead是入环结点。

其中L的长度等于M的长度,知道这个结论后代码就信手拈来了。

26eee60a802c45f9869772161dd0c98c.png

下面是证明L=M:

如果是环形链表那么两个指针会相遇,找到相遇的节点node:

716f01e27d0a48a1872a9670ee3cef17.png

那么如图设置:head到入环的结点的长度为L,入环到相遇的结点node的长度为N,环的长度为C:

50878075d6e449a780414561f6d5a651.png

那么开始遍历链表,当然慢指针slow入环时快指针已经在环里走了至少一圈,假设为x圈,

当快慢指针相遇时,慢指针在环里面走的长度就是N,因为快指针的相对于慢指针的速度为1,所以每走一步快指针就与慢指针的距离-1,直到相遇。


此时

快指针走的路程:L+N+x*C

慢指针走的路程:L+N

因为快指针的速度是慢指针的两倍,所以路程也是慢指针的两倍。

所以:

L+N+x*C=2*(L+N)

整理一下:

L=x*C-N

处理:

L=(x-1)*C+C-N

式中当x取最小值时:L=C-N

b9dc3a5267b74c2ab9671e38b7f5e2f0.png

而黑色部分长度就是C-N

此时让head遍历链表,node也开始往下走,当x取的值不是1时,node结点会一直在环里遍历,最终head和node一定会在入环结点相遇。


2.1代码
struct ListNode *detectCycle(struct ListNode *head) {
     struct ListNode *slow=head;
    struct ListNode *fast=head;
      struct ListNode *node=head;
    while(fast&&fast->next)
    {
        fast=fast->next->next;
        slow=slow->next;
        if(fast==fast)
        break;
    }
    if(fast==NULL||fast->next==NULL)
    return NULL;
    while(fast!=node)
    {
        
        fast=fast->next;
        node=node->next;
    }
    return fast;
}


目录
相关文章
|
1月前
|
存储 C语言 索引
环形链表、环形链表 II、有效的括号​​​​​​​【LeetCode刷题日志】
环形链表、环形链表 II、有效的括号​​​​​​​【LeetCode刷题日志】
|
1月前
|
索引
【每日一题】5.LeetCode——环形链表
【每日一题】5.LeetCode——环形链表
|
16天前
|
存储 算法 Java
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
【经典算法】Leetcode 141. 环形链表(Java/C/Python3实现含注释说明,Easy)
9 2
|
1月前
|
C++ Python Java
Java每日一练(20230501) 路径交叉、环形链表、被围绕的区域
Java每日一练(20230501) 路径交叉、环形链表、被围绕的区域
42 0
Java每日一练(20230501) 路径交叉、环形链表、被围绕的区域
|
26天前
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点.
<数据结构>五道LeetCode链表题分析.环形链表,反转链表,合并链表,找中间节点
23 1
|
26天前
|
存储 算法 索引
【力扣刷题】只出现一次的数字、多数元素、环形链表 II、两数相加
【力扣刷题】只出现一次的数字、多数元素、环形链表 II、两数相加
27 1
|
26天前
|
索引
【力扣刷题】回文链表、环形链表、合并两个有序链表
【力扣刷题】回文链表、环形链表、合并两个有序链表
20 0
|
1月前
|
索引
【力扣】142. 环形链表 II
【力扣】142. 环形链表 II
|
1月前
|
算法 C语言 索引
环形链表(快慢指针)
环形链表(快慢指针)
|
1月前
|
C语言 C++ 索引
【力扣】141. 环形链表、160. 相交链表、206.反转链表、234. 回文链表
【力扣】141. 环形链表、160. 相交链表、206.反转链表、234. 回文链表