力扣-环形链表II解题思路

前言

环形链表II-力扣
本题主要考察了对环形链表的掌握,逻辑思维和一些基本的数学能力

思路

一个环形链表大致可以看成这样
在这里插入图片描述
首先,我们该怎么判断此链表是环形呢?

我们先来看看这道题:环形链表-力扣

这道题让我们判断链表是否成环。可以使用快慢指针的方式,慢指针走一步,快指针走两步,当快指针与慢指针相遇时,则说明链表成环。

这种思路该怎么解释呢?

在这里插入图片描述

假设当slow指针走到环的入口时,fast指针与slow指针的距离为N。那么此时fast与slow指针每走一次,彼此的距离减一,最后为0。

bool hasCycle(struct ListNode *head) {
    struct ListNode* slow=head;
    struct ListNode* fast=head;
    while(fast&&fast->next){
        slow=slow->next;//慢指针走一步
        fast=fast->next->next;//快指针走两步
        if(slow==fast)//相遇时说明成环
            return true;
    }
    return false;
}

我们再回到环形链表II这道题。我们想要找到环的入口,可以用头指针与慢指针相遇的方法。原理是这样的,我们先设前缀路程为L,环的路程为C。当fast与slow相遇时,slow指针走过的路程为:L+N ,fast指针走过的路程为:L+x ∗ * C+N(x为绕环走过的圈数)。因为fast的路程等于slow指针的两倍,所以可以得出整式:2 ∗ * (L+N)=L+x ∗ * C+N。化简得:L=x ∗ * C-N。如图所示,此时slow与入口的距离为:C-N,所以如果此时头指针与slow指针同时出发,无论slow走几圈,都必定会再入口相遇。
在这里插入图片描述

代码

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode* slow=head;
    struct ListNode* fast=head;
    while(fast&&fast->next){
        slow=slow->next;
        fast=fast->next->next;
        if(fast==slow){
            struct ListNode* meet=slow;
            while(meet!=head){
                meet=meet->next;
                head=head->next;
            }
            return meet;
        }
    }
    return NULL;
}
  • 24
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值