Write a program to find the node at which the intersection of two singly linked lists begins.
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
最容易想到的解法是两链表同时遍历,遍历到相同节点时即为插入的节点,但是这种方法涉及到A和B长度不等的问题,所以要先判断他们的长度,然后令较长的链表优先开始遍历,直到遍历到与较短链表长度相等的位置时,才开始两链表同时遍历查找。
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode p1 = headA;
ListNode p2 = headB;
int len1 = 0;
int len2 = 0;
while (p1 != null){
len1 ++;
p1 = p1.next;
}
while (p2 != null){
len2 ++;
p2 = p2.next;
}
p1 = headA;
p2 = headB;
if (len1 < len2){
while (len1 < len2){
p2 = p2.next;
len2 --;
}
}
if (len1 > len2){
while (len1 > len2){
p1 = p1.next;
len1 --;
}
}
while (len1 > 0){
if (p1 == p2){
return p1;
}
else {
p1 = p1.next;
p2 = p2.next;
len1 --;
}
}
return null;
}
}
在discuss里看到一个人人称好的解法,就是先默认有intersection存在,将两条链表看成一个环进行遍历。当A.next为空时,指向headB,B.next为空时,指向headA,再遍历下去就会找到A == B,其实这种方法的本质也是通过环的循环令长链表比短链表多走一段,再实现同步。
public class Solution { //456ms
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null){
return null;
}
ListNode p1 = headA;
ListNode p2 = headB;
while (p1 != p2){
p1 = p1 == null ? headB : p1.next;
p2 = p2 == null ? headA : p2.next;
}
return p1;
}
}