题目:
找出两个单链表相交的起始点。
Write a program to find the node at which the intersection of two singly linked lists begins.
Input: intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 Output: Reference of the node with value = 8 Input Explanation: The intersected node's value is 8 (note that this must not be 0 if the two lists intersect). From the head of A, it reads as [4,1,8,4,5]. From the head of B, it reads as [5,0,1,8,4,5]. There are 2 nodes before the intersected node in A; There are 3 nodes before the intersected node in B.
思路:
A和B的差别只在公共节点之前的部分,如果能得知A和B的长度之差k,就可以先从长链表先走k步,再同时从短链表开始走,相遇时则为相交的起始点
所以问题就转变为了如何求A和B的长度之差
如果使用先遍历A得到长度lenA,再遍历B得到长度lenB,再根据差值重新遍历的方法,需要依次遍历三次,花费时间较长。
使用的方法:
1. 两个链表同时遍历,直到其中一个指针遍历到空指针;
2. 当一个链表遍历到底时,使用新指针指向还未遍历到底的链表头,并与旧指针开始同时往前遍历,直到旧指针遍历到空指针
3. 当旧指针遍历到底时,再使用一个新指针指向短链表(先被遍历完)的链表头,并与之前的新指针同时遍历。当两个指针相遇时,则为链表的相交起始点
代码:
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode oldL = headA;
ListNode oldS = headB;
ListNode newL,newS;
// 步骤一:长、短指针同时遍历
while(oldL!=null && oldS!=null) {
oldL = oldL.next;
oldS = oldS.next;
}
// 其中一个指针遍历到底
// 为了统一L、S与长短,如果是命名为L的链表先遍历到底,则交换下节点
// 根据情况,分别为长短的新指针指定开始位置
if(oldL==null) {
oldL = oldS;
newL = headB;
newS = headA;
}else {
newL = headA;
newS = headB;
}
// 步骤二
while(oldL!=null) {
oldL = oldL.next;
newL = newL.next;
}
// 步骤三
while(newL!=newS) {
newL = newL.next;
newS = newS.next;
}
return newL;
}
}