链表判断是否有环以及求环的入口点的原理

1.给定一个链表,判断链表中是否有环。

链表判断是否有环,使用快慢指针,快指针一次走两步,慢指针一次走一步,当快指针与慢指针相遇时,说明链表中有环。

问题:为什么快指针一次走两步,三次可以吗
答案:不可以,很有可能会一直错开

看图
在这里插入图片描述

bool hasCycle(struct ListNode *head) {
    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.给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 NULL.
解题思路:
第一步找出两个指针的相遇点,第二步让快指针从相遇点开始走,让慢指针从链表的最开始走,快慢指针每次各走一步,当两个指针相遇了,即是入口点。

在这里插入图片描述
终极版原理
在这里插入图片描述
上面的是n=1的情况下

struct ListNode *detectCycle(struct ListNode *head) {
    struct ListNode*fast=head;
    struct ListNode*slow=head;
    int pos=0;
    //判断有没有环
    while(fast!=NULL&&fast->next!=NULL)
    {
        fast=fast->next->next;
        slow=slow->next;
        if(slow==fast)
       {
pos=1;
        break;
       } 
    }
    //在有环的基础上找出第一个入口
    if(pos==1)
    {
        slow=head;
        while(slow!=fast)
        {
fast=fast->next;
slow=slow->next;
        }
        return slow;
    }return NULL;
}

发布了24 篇原创文章 · 获赞 4 · 访问量 2625

猜你喜欢

转载自blog.csdn.net/weixin_41548145/article/details/103288515