劍指offer 連結串列中環的入口節點
阿新 • • 發佈:2019-02-10
一個連結串列中包含環,請找出該連結串列的環的入口結點。
這個題目leetcode上做到過,當時的思路是先找到快慢指標的第一次交點。然後把其中一個指標放回頭部,兩者以相同速度前進,相遇點即是入口,這需要數學證明,不大容易想
該方法程式碼如下
public ListNode EntryNodeOfLoop(ListNode pHead){
ListNode slow = pHead;
ListNode fast = pHead;
while(slow != null && fast !=null && fast.next != null ){
slow = slow.next;
fast = fast.next.next;
if(slow == fast) break;
}
if(fast == null || fast.next == null) return null;
slow = pHead;
while(slow != fast){
slow = slow.next;
fast = fast.next;
}
return slow;
}
這次又多了兩種新思路:
這種方法會破壞連結串列的結構,但想法的確很不錯:
/*
時間複雜度為O(n),兩個指標,一個在前面,另一個緊鄰著這個指標,在後面。
兩個指標同時向前移動,每移動一次,前面的指標的next指向NULL。
也就是說:訪問過的節點都斷開,最後到達的那個節點一定是尾節點的下一個,
也就是迴圈的第一個。
這時候已經是第二次訪問迴圈的第一節點了,第一次訪問的時候我們已經讓它指向了NULL,
所以到這結束。
*/
public ListNode EntryNodeOfLoop2(ListNode pHead){
if (pHead == null) return pHead;
ListNode pre = pHead;
ListNode cur = pHead.next;
while(cur != null){
if(pre.next == null) return pre;
ListNode tmp = cur;
cur = cur.next;
pre.next = null;
pre = cur;
}
return null;
}
其實還有一種比較常規的想法
如果連結串列中環 有n個結點,指標P1在連結串列上向前移動n步,然後兩個指標以相同的速度向前移動。
當第二個指標指向環的入口結點時,第一個指標已經圍繞著環走了一圈又回到了入口結點。
所以首先要得到環中結點的數目。
這個程式碼就不寫了