算法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
浙公网安备 33010602011771号