题目:
Write a program to find the node at which the intersection of two singly linked lists begins.
Notes:
- 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.
解答:
解答一:
注意分析题目:寻找两个链表的起始相交节点,则两个链表从相交节点至链表结束这段长度一定相同,那么可以先将两个链表以右边为基准进行对齐,长链表比短链表多出来的左侧长度部分一定不包含相交节点,然后就令双指针分别指向两个链表长度相同的节点处。
- 先用两个while()循环,得出两个链表的长度lengthA,lengthB
- 判断lengthA和lengthB的长度,将较长链表的指针向后移,直至两个链表长度相同的节点处
- 双指针tempA,tempB逐次向后移动,判断headA==headB
注意: 这里的相交不是指值相等,而是指占用同一片内存空间。因此要判断headA==headB
,而不能判断headA.val==headB.val
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA==null||headB==null){
return null;
}
int lengthA=0;
int lengthB=0;
ListNode tempA=headA;
ListNode tempB=headB;
while(tempA!=null){
lengthA++;
tempA=tempA.next;
}
while(tempB!=null){
lengthB++;
tempB=tempB.next;
}
if(lengthA>=lengthB){
for(int i=0;i<lengthA-lengthB;i++){
headA=headA.next;
}
}else{
for(int i=0;i<lengthB-lengthA;i++){
headB=headB.next;
}
}
while(headA!=null&&headB!=null){
if(headA==headB){
return headA;
}
headA=headA.next;
headB=headB.next;
}
return null;
}
}
解答二:
还看到了另外一种思路,分别从两个链表的头节点开始,指针到达链表尾部时,两个链表的指针进行交换,继续遍历。
- 指针nodeA从headA开始,nodeB从headB开始
- nodeA和nodeB同时向后移动
2.1. 若nodeA==nodeB,则此处为焦点;
2.2 若nodeA或nodeB为空且未换路,则换路后继续移动;
2.3 若nodeA和nodeB均换路且到达尾部,则表示无交点,返回空
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA==null||headB==null){
return null;
}
ListNode nodeA=headA;
ListNode nodeB=headB;
boolean isAChanged=false;
boolean isBChanged=false;
while(nodeA!=null&&nodeB!=null){
if(nodeA==nodeB){
return nodeA;
}
nodeA=nodeA.next;
nodeB=nodeB.next;
if(isAChanged&&isBChanged&&nodeA==null&&nodeB==null){
break;
}
if(nodeA==null){
nodeA=headB;
isAChanged=true;
}
if(nodeB==null){
nodeB=headA;
isBChanged=true;
}
}
return null;
}
}