Leetcode140 环形链表(大白话说思路)——链表专题

思路:
判断是否有环,快慢指针相遇即有环
找环的入口,承接是否有环,相遇后将慢指针移到链表头,两个指针以相同每次移动一次的速度移动直到相等,返回当前节点即为答案

为什么找环的入口只要一个指针在相遇节点一个指针在链表头同时走,相遇即为环入口???
Leetcode140 环形链表(大白话说思路)——链表专题_第1张图片
slow指针在紫色节点时走过的路程等于a+b(为啥不是a+N*b,一定是第一圈被追上?见注1)
fast指针在紫色节点时走过的路程等于a+b+(b+c)*K

2 ( a + b ) = a + b + ( b + c ) ∗ K 化 简 后 为 a = ( K − 1 ) ∗ b + K ∗ c 2(a+b)=a+b+(b+c)*K化简后为a=(K-1)*b+K*c 2(a+b)=a+b+(b+c)Ka=(K1)b+Kc

所以在紫色相遇点fast走(K-1)*b + K*c路程一定能和从head出发的slow在环的入口处相遇

注1:
注意快指针是一定能在慢指针的第一圈追上慢指针的,假设最坏情况慢指针走到环上(快指针一定已经在环上了),快指针在他的下一个也就是慢指针领先他(b+c-1)个节点,那快指针就可以(b+c-1)后追上慢指针,慢指针走了b+c-1步依然没有走完一圈


//是否有环
class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode*slow = head;
        ListNode*fast = head;
        while(fast&&fast->next){
            slow = slow->next;
            fast = fast->next->next;
            if(slow==fast)return true;
        }
        return false;
    }
};



//寻找环的入口
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        int flag = false;
        ListNode*slow = head;
        ListNode*fast = head;
        while(fast&&fast->next){
            slow = slow->next;
            fast = fast->next->next;
            if(slow==fast){
                slow =head;
                while(true){
                    slow = slow->next;
                    fast = fast->next;
                    if(slow==fast)return slow;
                }
            };
        }
        return NULL;
    }
};

你可能感兴趣的:(面试,链表,leetcode,数据结构)