链表判断是否存在环以及环的入口

链表判断是否存在环

快慢指针的方法

class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode* plow = head;
        ListNode* pfast = head;

        while(pfast)
        {
            plow = plow ->next;
            pfast = pfast->next;
            if(pfast)
            {
                pfast = pfast ->next;
            }
            else
                return false;
            if(pfast == plow)
                return true;
        }
        return false;
    }
};

链表判断环的入口

快慢指针的方法:分为两个阶段,第一阶段先寻找是否有环,第二阶段通过快慢指针的回合点找到环的入口。

借用leetcode上的图来说明

1583137019239

首先环的长度为C,非环长度为F.

首先慢指针走到0处用了F步,快指针则走到了h处,h = F%C

接着满指针走\(C-h\)步,则快指针走到了$(2C- 2h + h)%C =C-h $,因此在此处相遇。

第二阶段,另外设一个指针在头部,向前走F步,相遇点的指针也向前走F步,则位置在\((C-h + F)\%C = 0\),此时相遇。

class Solution {
public:
    ListNode* EntryNodeOfLoop(ListNode* head)
    {
        bool isCircle = false;
        ListNode* fast = head;
        ListNode* low = head;
        while(fast)
        {
            low = low ->next;
            fast = fast->next;
            if(!fast)  return NULL;
            
            fast = fast->next;
            if(fast == low)
            {
                isCircle = true;
                break;
            } 
        }

        if(!isCircle)  return NULL;
        
        // second
        ListNode* pcur = head;
        while(pcur != low)
        {
            pcur = pcur->next;
            low = low->next;
        }
        return pcur;
    }
};

猜你喜欢

转载自www.cnblogs.com/hustyan/p/12404671.html