Write a program to find the node at which the intersection of two singly linked lists begins.
For example, the following two linked lists:
A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3
begin to intersect at node c1.
Notes:
- If the two linked lists have no intersection at all, return
null
. - The linked lists must retain their original structure after the function returns.
- You may assume there are no cycles anywhere in the entire linked structure.
- Your code should preferably run in O(n) time and use only O(1) memory.
查找两个链表的交叉点 即第一次出现相同节点的地方 使用哈希表 时间复杂度满足要求 但空间复杂度太高 代码如下:
Map<ListNode,Integer> hma=new HashMap<ListNode,Integer>();
Map<ListNode,Integer> hmb=new HashMap<ListNode,Integer>();
while(headA!=null||headB!=null){
if(headA!=null){
if(hmb.containsKey(headA)){
return headA;
}else{
hma.put(headA,1);
headA=headA.next;
}
}
if(headB!=null){
if(hma.containsKey(headB)){
return headB;
}else{
hmb.put(headB,1);
headB=headB.next;
}
}
}
return null;
第二个思路是 晾着若有公用部分 则链表各自部分的差与整个链表长度的差是相同的 所以 先分别算出链表长度 再让长度长的链表的指针先走 差值步 则保证两指针一起走 能一起到公共部分 此公共部分即时所求解 代码如下:
int lena=0;
int lenb=0;
ListNode pa=headA;
ListNode pb=headB;
while(pa!=null){
lena++;
pa=pa.next;
}
while(pb!=null){
lenb++;
pb=pb.next;
}
if(lena<=lenb){
int n=lenb-lena;
while(n>0){
headB=headB.next;
n--;
}
}else{
int n=lena-lenb;
while(n>0){
headA=headA.next;
n--;
}
}
while(headA!=headB){
headA=headA.next;
headB=headB.next;
}
return headB;