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和B链表,A走到tail时转到B的head,B走到tail时转到A的head
然后必然会走到相同的点
两个链表有交叉点的前提是后面的node必须有一致,如果走到tail还不一致,证明不存在交叉点,返回null
//1ms
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
ListNode a = headA;
ListNode b = headB;
while (a != null && b != null) {
if (a == b) {
return a;
}
a = a.next;
b = b.next;
if (a == null && b == null) {
return null;
}
if (a == null) {
a = headB;
}
if (b == null) {
b = headA;
}
}
return null;
}
方法二:
快慢指针法,
连接末尾和headA,形成一个环,于是转换为链表的环的问题。
快指针每次走2步,慢指针每次走一步,如果相遇则存在环,有一方走到null则不存在环,返回null(别忘了修改指针把环去掉)。
然后慢指针回到headB(因为A是环里面的),
快慢指针每次都走一步,它们相遇的地方就是环的入口。
由于这个环是自己添加的,所以返回前要把链表恢复到最初的状态。
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode tail = headA;
ListNode fast = headB;
ListNode slow = headB;
while(tail.next != null) {
tail = tail.next;
}
tail.next = headA;
while(true) {
if(fast == null || fast.next == null || slow == null) {
tail.next = null;
return null;
}
fast = fast.next.next;
slow = slow.next;
if(fast == slow) break;
}
slow = headB;
while(slow != fast) {
slow = slow.next;
fast = fast.next;
}
tail.next = null;
return slow;
}
本文介绍两种高效算法来解决寻找两个单链表开始相交节点的问题。方法一通过遍历两个链表,当到达尾部时转向另一链表的头部,直至找到相同节点或确定无交集。方法二采用快慢指针法,通过构造环形链表来识别相交点。
557

被折叠的 条评论
为什么被折叠?



