环形链表——快慢指针的使用

一.1.题目(141. 环形链表 - 力扣(LeetCode)

 2.题目思考

 对于这个题目就是判断是不是环形链表。那么是否可以使用一个指针来进行判断经过同一个点,得出是环形链表吗?答案是:不行。因为如果是环形链表的话,指针会不断循环,那么程序进入会死循环。所以,我们思考使用两个指针,一快一慢,当快指针能遇到慢指针时为环形链表。

此时题目就变成了追击问题 

3.代码实现 

bool hasCycle(struct ListNode *head) {

    struct ListNode*fast=head,*slow=head;

    while(fast&&fast->next)

    {

        fast=fast->next->next;

        slow=slow->next;

        if(fast==slow)

        {

            return true;

        }

    }

    return false;

}

二. 

1.进一步思考

(1).为什么题目1中一定会相遇,有没有可能会错过,永远追不上?

(2).slow走一步,fast走3步,4步,n步,也一定能追上吗?

(3).为什么一定相遇?有没有可能会错过。 

2.进一步分析

问题(1):fast走2步,slow走1步

也就是说,当fast追slow的过程中,距离的变化为N-1,N-2,N-3,---,3,2,1,0。当fast与slow的距离为0时就追上了。 


问题(2)(3):假设fast走3步,slow走1步。

 我们可以暂时得出一个结论:

1.当N是偶数时第一次就追上了

2.当N是奇数时 ,第一次会错过,进入下一轮

(当c是奇数,也就是c-1是偶数时,追上了;当c是偶数时,也就是c-1是奇数时,追不上)

那么就是同时存在N是奇数且c是偶数时,fast永远追不到slow。

那么这个结论是否正确,我们要使用数学进行计算一下

那么上面的结论可以的出并不正确, N是奇数且c是偶数时的条件不能同时出现,永远追不上的条件不能成立。

因此我们的出新的结论:

1.一定能追上

2.当N是偶数时第一次就追上了

3.当N是奇数时 ,第一次会错过,进入下一轮。

三.1.题目(142. 环形链表 II - 力扣(LeetCode)

 2.代码实现

struct ListNode* detectCycle(struct ListNode* head) {

    struct ListNode *fast = head, *slow = head;

    while (fast && fast->next) {

        fast = fast->next->next;

        slow = slow->next;

        if (slow == fast) {

            struct ListNode* meet = slow;

            while (meet != head) {

                meet = meet->next;

                head = head->next;

            }

            return meet;

        }

    }

    return NULL;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值