Question
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.
Note
- 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.
Java Code
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null)
return null;
ListNode i = headA;
ListNode j = headB;
int lenA = 1;
int lenB = 1;
//统计两个链表的长度
while((i = i.next) != null) lenA++;
while((j = j.next) != null) lenB++;
//指针i总是指向较长的链表,计算较长链表中需要忽略的前若干个节点
int ignore = 0;
if(lenA >= lenB) {
ignore = lenA - lenB;
i = headA;
j = headB;
}else {
ignore = lenB - lenA;
i = headB;
j = headA;
}
//将节点指针i移到第ignore个节点处
for(int count = 0; count < ignore; ++count)
i = i.next;
//同时遍历两个链表,直到遇到第一个相交的节点
while(i != null){
if(i == j)
return i;
else {
i = i.next;
j = j.next;
}
}
//遍历完所有节点也没找到相交节点
return null;
}
说明
- 本题如果没有好的处理办法,那么解决问题会很麻烦,而且复杂度也达不到要求。我们可以通过分析发现,两个有交集的单向链表在相交之后实际上就合并为一条链表了,所以可以找到两者在长度上的等量关系,从而可以轻松地找到两者的第一个交点。