写点什么

链表专项之环形链表

作者:lovevivi
  • 2022-10-19
    吉林
  • 本文字数:1690 字

    阅读完需:约 1 分钟

@TOC



前言


1.141. 环形链表

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



/** * Definition for singly-linked list. * struct ListNode { *     int val; *     struct ListNode *next; * }; */bool hasCycle(struct ListNode *head) {    struct ListNode*fast=head;    struct ListNode*slow=head;    while(fast!=NULL&&fast->next!=NULL)    {        slow=slow->next;        fast=fast->next->next;         if(slow==fast)        {            return true;        }    }   return false; }
复制代码


这道题的思考还是比较简单的 使用快慢指针两者从 head 开始快指针每次走 2 步慢指针每次走 1 步如果是循环链表则 一定能使快指针追上慢指针也要注意一个问题 判断 slow 指针与 fast 指针是否相等 ,是在移动一次之后因为 开始定义的时候就是相等的

证明为什么快指针一定为 2 步,慢指针一定为 1 步

1.当循环链表前的距离与循环链表后的距离相等时


   >当slow指针走到循环开始时,fast指针已经走完一圈了,所以两者处于相同位置
复制代码

2.当循环链表前的距离为循环链表后的距离的 1/2


fast 一次走 2 步,slow 一次走 1 步当 slow 走到循环开始的位置, fast 已经走到循环的一半按照顺时针的顺序 fast 追 slow, 两者之间的距离为 x 当 fast 与 slow 每走一次则之间的距离减少 1 即 x-1,x-2,x-3,x-4,x-5,x-6........无论 x 为奇数或者偶数 两者一定能相遇

同种情况下,fast 走 N 步,slow 走 1 步

依旧假设 fast 指针与 slow 指针之间的距离为 x 若 fast 指针一次走 3 步,slow 指针一次走 1 步则 slow 与 fast 每走一次距离减少 2x-2,x-4,x-6,x-8,x-10.....x 若为偶数则能成功遇见 ,若为奇数 就会一直错过 ,造成死循环


同理 若 fast 指针一次走 4 步,slow 指针一次走 1 步两者之间每次减少 3x-3,x-6,x-9,x-12.....若 x 为奇数则能成功遇见,若为偶数 就会一直错过,造成死循环

142. 环形链表 II

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



/** * Definition for singly-linked list. * struct ListNode { *     int val; *     struct ListNode *next; * }; */struct ListNode *detectCycle(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)        {           struct ListNode*cur=slow;            while(head!=cur)            {                cur=cur->next;                head=head->next;            }            return cur;
} } return NULL;
}
复制代码


这道题需要一个公式,这个公式需要推导下它分为 正常情况与特殊情况

公式的推导

1.正常情况


fast 走 2 步,slow 走 1 步没循环的链表距离为 L ,slow 在循环链表中走的距离为 X,循环链表一圈距离为 Cslow 走的长度为 L+X,fast 在循环链表为 L+C+X 当 fast 与 slow 相遇时 fast 是 slow 走的 2 倍即 2(L+X)=L+C+XL=C-X 相当于 head 到交点的距离等于相遇点到交点的距离

2.特殊情况


没循环的链表距离为 L ,slow 在循环链表中走的距离为 X,循环链表一圈距离为 C 当循环链表 C 很小时则当 slow 刚进入循环时,fast 已经转了 N 圈当 fast 与 slow 相遇时即 2(L+X)=L+N * C+X 即 L=N*C-X 此时的 N * C 代表从相遇点处开始的 N 圈 减去 x 正好为相遇点所以 N 的数量不会影响依旧从 fast 与 slow 的相遇点开始 到交点的距离与 head 到交点的距离相等

用户头像

lovevivi

关注

还未添加个人签名 2022-10-12 加入

还未添加个人简介

评论

发布
暂无评论
链表专项之环形链表_c_lovevivi_InfoQ写作社区