先參考第141題,判斷鏈表中是否有環
public class Solution {
public boolean hasCycle(ListNode head) {
if(head==null) return false;
ListNode walk = head;
ListNode run = head;
while(run.next!=null && run.next.next!=null){
walk = walk.next;
run = run.next.next;
if(walk==run) return true;
}
return false;
}
}
整體思路為,有兩個指針,一個每次走一步,一個每次走兩步,如果最后兩個指針能相遇,則肯定在鏈表中存在環,先不管他們各自繞了多少圈。
再看142題,不止要判斷是否有環,還要返回環開始的節點。
public class Solution {
public ListNode detectCycle(ListNode head) {
if(head==null) return null;
ListNode walk = head;
ListNode run = head;
while(run.next!=null && run.next.next!=null){
walk = walk.next;
run = run.next.next;
if(walk==run){
ListNode slow = head;
while(slow!=walk){
slow = slow.next;
walk = walk.next;
}
return slow;
}
}
return null;
}
}
先看代碼,整體思路跟141題差不多,只是在判斷出有環后,還要進行一步操作,這步操作的意思如下。
假設兩個指針,run和walk,
假設walk走了
A+B步(A為從頭節點走到環開始的距離,B為在環內走的距離)
那么run走了2(A+B)步,因為run每次走兩步
設環長為N
則
A+B+N=2A+2B
N=A+B
此時再增加一個從頭開始走的指針,slow,他走到環的距離為A,那么,slow走了A步,walk走了A+B+A步,又引文N=A+B,那么slow和walk肯定會匯合在A處,即他們相遇的地方即為環開始的地方。