LeetCode142——Linked List Cycle II

带环链表问题的进阶版,不仅要判断是否存在环,还要找出环回的位置。题面如下:
在这里插入图片描述
这道题在原本快慢指针的基础上加入了更多的操作细节,简而言之,快慢指针的相遇与否可以说明链表中是否存在环路(这在另一篇博客中已经记录过),但是这并不能直接反映出相交的位置,这里面涉及到一个简单的数学推导:官方题解中给出了完整的推导
总而言之,这个推出的结论就是本题的解题关键,也是难点:

当Slow和Fast指针相遇时,我们再使用一个指针从链表头部与Slow指针一齐向后运动,最终两者一定会交汇在链表的环回处。

这个结论在理解原理的基础上可以记下,下面准备给出源代码。
和之前一样,我写了专门的两个函数来负责指针的移动:oneStepForwardtwoStepForward,也就是负责将指针向前移动一个和两个位置,代码如下:

/*move the pointer one position forward*/
    bool oneStepForward(ListNode*& Ptr)
    {
    
    
        if(Ptr && Ptr->next)
        {
    
    
            Ptr = Ptr->next;
            return true;
        }
        else
            return false;
    }

    /*move the pointer two positions forward*/
    bool twoStepForward(ListNode*& Ptr)
    {
    
    
        if(oneStepForward(Ptr) && oneStepForward(Ptr))
            return true;
        else
            return false;
    }

随后移动指针,确定是否有环存在(必须要确定是否存在环路):

		/*slow-fast pointers algorithm*/
        while(true)
        {
    
    
            /*move the two pointers*/
            if(oneStepForward(SlowPtr) && twoStepForward(FastPtr))
            {
    
    
                /*the 2 pointers meet, jump out of the loop*/
                if(SlowPtr == FastPtr)
                    break;
            }
            /*no cycle in the list*/
            else
                return nullptr;
        }

最后根据上述的结论,既然已经找到了快慢指针的交汇点,就使用一个从链表头部开始的指针(这里是Result),同步的和慢指针SlowPtr一步步的移动,直至它们相遇,这个交点就是环回点,且一定存在,找到后返回即可。

		/*get the intersection node*/
        while(Result != SlowPtr)
        {
    
    
            Result = Result->next;
            SlowPtr = SlowPtr->next;
        }
        
        return Result;

猜你喜欢

转载自blog.csdn.net/zzy980511/article/details/119378236