算法day13 环形链表

题目描述

思路:快慢指针

关于检测链表是否有环的问题我们可以将其抽象为一道追击问题。我们设置两个指针,一个快指针,一个慢指针。快指针每一次移动两个步进,慢指针每一次移动一个步进,相当于快指针相对于慢指针每一次移动一个步进,所以快指针一定能够追上慢指针与其相遇。我们假设相遇的位置为meet,环的入口位置为gate,则整个过程我们可以拆分为三个部分:

慢指针到达MEET的路途为x+y;
快指针到达MEET的路途为(x+y+n(y+z));
所以二者相遇的等式应该是2(x+y)= x+y+n(y+z);
整理移项后:x = (n-1)y+nz;
令n=1,则 x = z;   //n>=1;
也即而这相遇后再设置两个指针一个由HEAD出发,一个由MEET出发,它们会在GATE处相遇。

最后返回相遇时的指针即可找到入口。

代码如下

    ListNode *detectCycle(ListNode *head) {
    ListNode *slow = head; //慢指针
    ListNode *fast = head; //快指针
    while(fast&&fast->next){
       slow = slow -> next;     
       fast = fast -> next -> next;
       if(fast==slow){ //找到相遇位置
        ListNode *index1 = fast;
        ListNode *index2 = head;
        while(index1!=index2){//找到入口
            index1 = index1 -> next;
            index2 = index2 -> next;
        }
        return index1; //返回
       }
    }

    return nullptr;
}

时间复杂度:O(n)
空间复杂度:O(1)

END

posted on 2025-04-18 20:56  sakura430  阅读(11)  评论(0)    收藏  举报