尋找鏈表的環入口點
最常見的解題思路,即使用快慢指針來解決該問題
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public Entry loopEntry(){
if(headEntry == null || headEntry.next == null){
return null;
}
if(headEntry.next == headEntry)
return headEntry;
Entry<T> fast = headEntry,slow = headEntry;
do{
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
fast = headEntry;
do{
fast = fast.next;
slow = slow.next;
if(fast == slow){
return fast;
}
}while(fast != null && fast.next !=null);
}
}while(fast != null && fast.next !=null);
return null;
}
兩個鏈表的相交結點(返回指定的結點值)
力扣上有這樣一道題:編寫一個程序,找到兩個單鏈表相交的起始節點。
但是看它的示例我們可以看出,並不是簡單的尋找兩個鏈表值相同的結點,是返回特定的結點。
上述的性質,我們通過力扣給出的幾個示例來看,就可以清楚了:
將該問題模擬成一個鏈表,則兩個鏈表相差的長度,相當於單鏈表中頭節點到相交結點的距離。
- 創建兩個指針p和q,分別初始化爲鏈表 A 和 B 的頭結點。然後讓它們向後逐結點遍歷。
- 當 p 到達鏈表的尾部時,將它重定位到鏈表 B 的頭結點; 類似的,當q 到達鏈表的尾部時,將它重定位到鏈表 A 的頭結點。將兩個鏈表在邏輯上模擬成一條鏈表。
- 若在某一時刻 p 和 q 相遇,則 p/q 爲相交結點。
想弄清楚爲什麼這樣可行, 可以考慮以下兩個鏈表: A={1,3,5,7,9,11} 和B={2,4,9,11},相交於結點 9。 由於 B.length (=4) < A.length (=6),q 比 p 少經過2 個結點,會先到達尾部。將 q 重定向到 A 的頭結點,p重定向到 B 的頭結點後,q 要比p 多走 2 個結點。因此,它們會同時到達交點。 - 如果兩個鏈表存在相交,它們末尾的結點必然相同。因此當p/q 到達鏈表結尾時,記錄下鏈表 A/B 對應的元素。若最後元素不相同,則兩個鏈表不相交。
class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode p = headA, q = headB;
while (p != q) {
p = p != null ? p.next : headB;
q = q != null ? q.next : headA;
}
return p;
}
}