LeetCode——Linked List Cycle II

本文介绍了一种有效的方法来确定链表中环的起始节点。通过使用快慢指针技巧,当快指针速度是慢指针两倍时,两者相遇于环内某点,将任一指针移回头部并保持相同速度前进,再次相遇点即为环的起始位置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       若同时从一个环的某个点出发,fast指针每次走两步,slow指针每次走一步,则可证明slow指针走回起点时,fast指针也恰好到达起点。两种思路:一、fast指针每次比slow指针多走一步,fast指针想与slow指针同时到达某点,必须超过slow指针一圈,每次多走一步,假设环的节点数为N,则多走一圈需要走N次,此时slow指针恰好走完一圈指向出发点,fast指针亦然;二、fast指针的速度是slow的两倍,slow走k步,fast就走了2k步,fast指针要超过slow指针一圈即N步,即2k-k=N,一个很简单的方程,得k=N,所以slow指针走N步回到出发点时,fast和slow指针再次指向同一点。

       那该怎么求解本题呢?设slow指针到达环的起始点要走k步,则fast指针此时已走了2k步,按照前述,fast指针想“赶上”slow指针需要走N-k次,此时fast和slow指针位于距环的起始点N-k步的位置,但N-k是指从起始点到这个点的步数,我们不能往回走,只能往前走,所有想再次回到起始点,必须再走N-(N-k)即k步。于是思路就很清晰了:先找出fast和slow指针“重合”即相等的地方,此时令slow = head,slow和fast每次只走一步,当走了k步(这个值不重要,只须判断fast和slow是否相等即可)fast和slow指针指向同一个节点使,这个节点即是环的起始点。若不存在这样的点,返回空指针。


<pre name="code" class="cpp">/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        
        ListNode *slow = head;
        ListNode *fast = head;
        while(fast && fast->next)
	{
	    slow = slow->next;
            fast = fast->next->next;
          
            if (slow == fast){
                slow = head;
                while (slow != fast)
		{
                    slow = slow->next;
                    fast = fast->next;
                }
                return slow;
            }
        }
        
        return NULL;
    }
};




                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值