bool hasCycle(struct ListNode *head) {
struct ListNode* slow = head;
struct ListNode* fast = head;
//①假设链表不存在环:
//1.当链表节点总个数为奇数个N时,则第二个节点到尾节点共有N-1偶数个节点(包括第二个节点)
//则经过有限次2连跳,快指针将到达尾节点,此时由于fast->next ==NULL,故循环结束
//2.当链表节点总个数为偶数个N时,则第二个节点到尾节点共有N-1奇数个节点(包括第二个节点)
//则经过有限次2连跳,快指针将到达尾节点的前一个节点,此时循环继续,但进行到
//fast = fast->next->next时,fast被赋予NULL,而结束循环
//总结:假设链表无环,如果链表共奇数个节点,则不满足fast->next != NULL而结束循环
// 如果链表共偶数个节点,则不满足fast != NULL而结束循环
while((fast != NULL) && (fast->next != NULL)){
slow = slow->next;
fast = fast->next->next;
//如果快慢指针相遇,说明环存在
if(slow == fast){
return true;
}
}
return false;
}
思路:采用快慢指针实现,如果存在环,快指针一定追上慢指针,如果不存在环,快指针走到链表尽头。
假设存在环
1. 假设存在环,如果slow每次走1步,而fast每次走2步,请问slow 和 fast是否一定会在环里面相遇?
答:一定会。假设slow进入环时,这时fast 与 slow 相差 N 个节点,由于slow每次走1步,而fast每次走2步,故每走一次,fast 和 slow 之间距离减少1,一定会在未来某次中,该距离减为0,故一定会相遇。
2. 假设存在环,且环中节点总数为sum,如果slow每次走1步,而fast每次走3步,请问slow 和 fast是否一定会在环里面相遇?
答:不一定。假设slow进入环时,这时fast 与 slow 相差 N 个节点,由于slow每次走1步,而fast每次走3步,故每走一次,fast 和 slow 之间距离减少2.
1)如果一开始N为奇数,则多次减2之后,这个距离就会变成-1(即fast是slow前的节点),如果这时环的总节点sum又是偶数,则下次追逐过程中,N的初始值再次变为奇数,如此往复,fast永远追不上slow.
2)如果一开始N为偶数,则多次减2之后,这个距离就会变成0,这种情况下fast就能追上。
3. 假设存在环,且环中节点总数为sum,如果slow每次走1步,而fast每次走4步,请问slow 和 fast是否一定会在环里面相遇?
答:不一定。假设slow进入环时,这时fast 与 slow 相差 N 个节点,由于slow每次走1步,而fast每次走4步 故每走一次,fast 和 slow 之间距离减少3.多次走后,N可能是0,也可能是-1,也可能是-2,而导致后面也像2一样一直循环追不上。