快慢指针判断环形链表

目录

判断环形链表 

寻找入环节点 


判断环形链表 

141. 环形链表 - 力扣(LeetCode) (leetcode-cn.com)

我们判断的结果无外乎两种情况----是环形链表或不是环形链表。

89245e7df00745bdbb9acc0e3bb51ddc.png

b0e855f698b7402db4a36aff8d30be20.png

因此如果有个指针指向了NULL,那么就证明了这不是个环形链表。但是如果要是环形链表,那么指针就会在环中一直寻找NULL,因此程序就会陷入死循环,这里就需要用快慢指针(详见上篇文章)来解决这个问题。

slow=slow->next;
fast=fast->next->next;

 这里我们可以理解为fast与slow两人正在跑步,当slow跑一步时,fast跑两步。当slow在进环后,fast一定能在一圈内追上slow,这是因为在追击过程中,他们之间的距离每次缩短1,他们之间的相对距离最多是1圈,这样slow最多走一圈,fast最多走两圈。这样在一个环形跑道中的fast总会与slow相遇的,而当fast与slow相遇时就能证明这是一个环形链表了。

bool hasCycle(struct ListNode *head) {
    struct ListNode *fast=head;
    struct ListNode *slow=head;
    while(fast&&fast->next)//如果没有环的话,fast肯定会比slow先遇到null
    {
        slow=slow->next;
        fast=fast->next->next;
        if(fast==slow)
        {
            return true;
        }
    }
    return false;
}

寻找入环节点 

142. 环形链表 II - 力扣(LeetCode)

在寻找节点之前我们要知道一个公式L=(N-1)*C+(C-X).

在上文中我们可以知道,只要快指针和慢指针相遇了,就表示这个链表带环,而且我们可以知道相遇的点meet,在上图中就是4。 此时slow走的路程就是L+X,fast所走的路程就是L+N*C+X (N>=1,N表示在slow进环之前fast在环内转了N圈)。

因为快指针所走的距离是慢指针的二倍,因此我们能得出一个等式2*(L+X)=L+N*C+X,由这个等式可以推导出 L=N*C-X,即L=(N-1)*C+(C-X)。这时我们再建立一个head指针从头开始走,当走了C-X步后,meet正好走到入环节点的位置,head剩下的路程就是N*C了(N>=0),因此meet与head相遇的点就是入环的节点。

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(slow==fast)
        {
        struct ListNode *meet=slow;
        while(meet!=head)
        {
            head=head->next;
            meet=meet->next;
        }
        return meet;
        }
    }
    return NULL;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值