数据结构 | 详解两道环形链表算法题

今日快报:女大勇闯蓝桥杯C/C++A组,空手而归,痛失300大洋!心碎成渣渣,遂写博客!😭😭

目录

1.141.环形链表

⛱️试题链接戳这里!

🍉精华思路

🌴深度剖析

❓️为什么fast一次走2步,而不是3步或者更多?

🥳代码实现

2.142.环形链表II

⛱️试题链接戳这里!

🍉精华思路

🌴深度剖析

🥳代码实现


1.141.环形链表

⛱️试题链接戳这里!

🍉精华思路

1️⃣设fast指针1次走2步,slow指针1次走1步❌环形链表

2️⃣当fast为NULL或者fast->next为NULL✅环形链表

🌴深度剖析

❓️为什么fast一次走2步,而不是3步或者更多?

设环长度为C,步数差为X

当slow进环时,fast已在环中顺时针走了N步

那么此时fast距离slow有C-N步

每移动一次,它们之间的距离就会缩短x

当slow=1,fast=2时,x=2-1=1:

那么,再移动(c-N)/1=c-N次,fast就可以追上slow

当slow=1,fast=3时,x=3-1=2:

1.当C-N为偶数时

再移动(C-N)/2次,fast就可以追上slow

2.当(C-N)为奇数时

那么这次肯定就追不上。

并且fast和slow之间的距离变为C-1

当c-1为偶数,即C为奇数时

再移动(C-1)/2次就能追上了

当C-1为奇数,即C为偶数时

那么又会遇不到slow,并且再次超过它1步,距离又变为C-1,陷入死循环,永远追不到

因此,步数差保证为1,即设置slow走1步,fast走2步,只要有环存在,是一定可以相遇的,而步数差>=2,则有可能永远相遇不到。

🥳代码实现

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


    

2.142.环形链表II

​​​​​​

⛱️试题链接戳这里!

🍉精华思路

前半段思路和上道题一样,

设置slow,fast指针,

slow指针每次走1步,fast指针每次走2步

如果可以相遇则说明有环存在。

当相遇后,另外设置一个指针p1,从起点出发,一次走1步

而相遇处也设置一个指针p2,一次走1步

p1和p2指针相遇的位置就是环链表的起点位置。

🌴深度剖析

下面对上面的思路进行验证:

设线段长L,设环长度为C

设当slow,fas相遇时,fast已在环中走了x个完整的圈

slow在环内刚走了N步

相遇时,slow路程:L+N

fast路程:L+xC+N

可列出方程式:

L+XC+N=2(L+N)

XC-L-N=0

(X-1)C+C-N-L=0

L=(X-1)C+C-N

那么,以相遇点为起点的p2,走到环链表的路程为(C-N)+XC (X=0,1,2,3…)

P1走到环链表的路程为L

由上式可得:L=(X-1)C+C-N

即两点的确可同时到达环链表起点处

🥳代码实现

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode *detectCycle(struct ListNode *head) {
     if(head == NULL){
            return NULL;
        }
        struct ListNode* fast = head;
        struct ListNode* slow = head;
        struct ListNode* p1 = head;
      
        while(fast != NULL && fast->next!=NULL){
            fast = fast->next->next;
            slow = slow->next;
            if(fast == slow){
                struct ListNode* p2 = slow;
                while(p1!=p2){
                    p1=p1->next;
                    p2=p2->next;
                }
                return p1;
            }
        }
       return NULL;
}

看到这里,不要忘了点赞收藏~

  • 31
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值