思路1:
1.先確定兩個鏈表有沒有相交
2.有的話,最後一個結點一定相同
3.遍歷兩個鏈表到末尾,判斷相同與否,順便計算兩個鏈表長度
4.計算長度差,然後求出相交鏈表的頭節點
代碼1:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
//先判斷鏈表是否相交,相交的話最後一個結點一定一樣
ListNode a = headA;
ListNode b = headB;
int la = 0,lb =0;
while(a!=null){
a = a.next;
la++;
}
while(b!=null){
b = b.next;
lb++;
}
//沒有相交
if(a != b) return null;
ListNode a1 = headA;
ListNode b1 = headB;
//走完長度差
if(la>=lb){
for(int i=0; i<la-lb; i++){
a1 = a1.next;
}
}else{
for(int i=0; i<lb-la; i++){
b1 = b1.next;
}
}
//尋找第一個交點
while(a1!=null && b1!=null){
if(a1 == b1) return a1;
a1 = a1.next;
b1 = b1.next;
}
return null;
}
}
代碼很長,但很容易懂。
思路2:
可以將兩個鏈表的元素都壓入棧,然後彈出最後一個相同的元素,即是第一個相交的結點。效率是很低的。
代碼2:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA ==null || headB ==null) return null;
ListNode a = headA;
ListNode b = headB;
Stack<ListNode> stackA = new Stack<>();
Stack<ListNode> stackB = new Stack<>();
while(a!=null){
stackA.add(a);
a = a.next;
}
while(b!=null){
stackB.add(b);
b = b.next;
}
//棧頂元素相等
ListNode tmp = null;
while(!stackA.isEmpty()&& !stackB.isEmpty()){
if(stackA.peek() == stackB.peek()){
tmp = stackA.pop();
stackB.pop();
}
else{
break;
}
}
return tmp;
}
}
思路3:
遍歷鏈表 A 並將每個結點的地址/引用存儲在哈希表中。然後檢查鏈表 B 中的每一個結點是否在哈希表中。若在,則爲相交結點。
思路4:
A+B和B+A的長度是相同的,所以遍歷A+B和遍歷B+A一定是同時結束。 如果A,B相交的話A和B有一段尾巴是相同的,所以兩個遍歷的指針一定會同時到達交點 如果A,B不相交的話兩個指針就會同時到達A+B(B+A)的尾節點.
代碼4:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA ==null || headB ==null) return null;
ListNode a = headA;
ListNode b = headB;
while(a!=b){
a = (a == null) ? headB : a.next;
b = (b == null) ? headA : b.next;
}
return a;
}
}