请写一个程序,找到两个单链表最开始的交叉节点。
注意事项
- 如果两个链表没有交叉,返回
null
。 - 在返回结果后,两个链表仍须保持原有的结构。
- 可假定整个链表结构中没有循环。
样例
下列两个链表:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
在节点 c1 开始交叉。
挑战
需满足 O(n) 时间复杂度,且仅用 O(1) 内存。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
/**
* @param headA: the first list
* @param headB: the second list
* @return: a ListNode
*/
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode nodeA = headA;
ListNode nodeB = headB;
int sizeA=0, sizeB=0;
while(nodeA!=null && nodeB!=null){
if(nodeA==nodeB)
return nodeA;
nodeA = nodeA.next;
sizeA++;
nodeB = nodeB.next;
sizeB++;
}
while(nodeA!=null){
nodeA = nodeA.next;
sizeA++;
}
while(nodeB!=null){
nodeB = nodeB.next;
sizeB++;
}
if(sizeA>sizeB)
return getCross(headA, headB, sizeA, sizeB);
else
return getCross(headB, headA, sizeB, sizeA);
}
ListNode getCross(ListNode longNode, ListNode shortNode, int longSize, int shortSize){
while(shortSize<longSize){
longNode = longNode.next;
longSize--;
}
while(shortNode!=null){
if(longNode==shortNode)
return shortNode;
longNode = longNode.next;
shortNode = shortNode.next;
}
return null;
}
}