160.相交連結串列
編寫一個程式,找到兩個單鏈表相交的起始節點。
例如,下面的兩個連結串列:
A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3
在節點 c1 開始相交。
注意:
- 如果兩個連結串列沒有交點,返回
null
. - 在返回結果後,兩個連結串列仍須保持原有的結構。
- 可假定整個連結串列結構中沒有迴圈。
- 程式儘量滿足 O(n
解法一:如果兩個鏈長度相同的話,那麼對應的一個個比下去就能找到,所以只需要把長連結串列變短即可。具體演算法為:分別遍歷兩個連結串列,得到分別對應的長度。然後求長度的差值,把較長的那個連結串列向後移動這個差值的個數,然後一一比較即可。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA==null|| headB==null) return null;
ListNode dummy1=new ListNode(0);
ListNode dummy2=new ListNode(0);
dummy1.next=headA;
dummy2.next=headB;
ListNode curA=dummy1;
ListNode curB=dummy2;
int length1=getLength(curA);
int length2=getLength(curB);
if(length1>length2)
{
for(int i=0;i<length1-length2;i++)
{
curA=curA.next;
}
}else{
for(int i=0;i<length2-length1;i++)
{
curB=curB.next;
}
}
while (curA != null && curB != null && curA != curB) {
curA = curA.next;
curB = curB.next;
}
return (curA != null && curB != null) ?curA : null;
}
private int getLength(ListNode cur)
{
int k=0;
while(cur.next!=null)
{
k++;
cur=cur.next;
}
return k;
}
}
解法二:
我們可以用環的思想來做,我們讓兩條連結串列分別從各自的開頭開始往後遍歷,當其中一條遍歷到末尾時,我們跳到另一個條連結串列的開頭繼續遍歷。兩個指標最終會相等,而且只有兩種情況,一種情況是在交點處相遇,另一種情況是在各自的末尾的空節點處相等。為什麼一定會相等呢,因為兩個指標走過的路程相同,是兩個連結串列的長度之和,所以一定會相等。這個思路真的很巧妙,而且更重要的是程式碼寫起來特別的簡潔
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA==null|| headB==null) return null;
ListNode a = headA, b = headB;
// while(a != b)
// {
// if(a==null) a=headB;
// else
// a=a.next;
// if(b==null) b=headA;
// else
// b=b.next;
// }
while (a != b) {
a = (a != null) ? a.next : headB;
b = (b != null) ? b.next : headA;
}
return a;
}
}
或者
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA==null|| headB==null) return null;
ListNode a = headA, b = headB;
while(a != b)
{
if(a==null) a=headB;
else
a=a.next;
if(b==null) b=headA;
else
b=b.next;
}
// while (a != b) {
// a = (a != null) ? a.next : headB;
// b = (b != null) ? b.next : headA;
// }
return a;
}
}