判断链表中是否有环,并查找链表环入口
使用快慢指针判断链表是否有环
使用一个慢指针slow,每次前进一步;一个快指针fast,每次前进两步。如果链表中没有环,快指针会先到达链表尾(NULL);如果链表中有环,快慢指针会相遇。
bool IsCycle(ListNode *head){
ListNode *slow = head;
ListNode *fast = head;
while(fast && fast->next){
fast = fast->next->next;
slow = slow->next;
if(fast == slow){
true;
}
}
return false;
}
查找链表环入口
设链表中节点数为size,入口节点序号x(0~size-1),慢指针前进s步后与快指针相遇。此时慢指针在环中走动步数为s-x,快指针在环中步数为2s-x。因为快慢指针相遇时相差步数一定为环中节点整数倍,可得:
n*r=2s-x-(s-x)=s
由上,慢指针在走x步,所走步数为环中节点数整数倍,即慢指针会指向链表环入口节点。
让指针p从链表头开始每次前进一步,慢指针也每次前进一次,p指针到达环入口时刚好x步,此时指针p等于慢指针slow.
ListNode *detectCycle(ListNode *head) {
ListNode *slow = head;
ListNode *fast = head;
while(fast && fast->next){
fast = fast->next->next;
slow = slow->next;
if(fast == slow){
break;
}
}
if(!fast) return NULL; // no circle
fast = head;
while(fast != slow){
slow = slow->next;
fast = fast->next;
}
return fast;
}