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: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3
begin to intersect at node c1.
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.
Credits:
Special thanks to @stellari for adding this problem and creating all test cases.
public class ListNode {
int val;
ListNode next;
ListNode(int x) {
val = x;
next = null;
}
}
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
}
分析:
这是一个链表的问题,并且已经给出了链表的数据结构的定义。
简而言之,就是给你2个链表,返回两个链表相遇的那个节点。
注意:
1,如果2个链表没有相遇,返回null。
2,函数返回时,不破坏给定的两个链表(java不是值传递么?)
3,假定在整个链表中,是没有环的。
4,你的实现必须是O(n)时间复杂度。O(1)空间复杂度。
解法:
分别遍历两个链表,记录长度(若已知则不需此步),短链表从头结点开始,长链表从第| list1.len - list2.len | 个节点开始,依次遍历并比较,相等的第一个节点则为相交的第一个节点。也可以使用hash法如(2)所示。
格外注意,函数的实参有可能是null的。
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA==null||headB==null) return null;
ListNode tempA=headA;
ListNode tempB=headB;
//1计算2个链表的长度。
//短的从头开始,长的从长-短的位置开始,因为长度一样了,遍历判断方便多了
int lengthA=1;int lengthB=1;
while(tempA.next!=null){
lengthA++;
tempA=tempA.next;
}
while(tempB.next!=null){
lengthB++;
tempB=tempB.next;
}
//开始循环遍历
int diff = Math.abs(lengthA-lengthB);
if(lengthA>lengthB) while(diff>0){
headA=headA.next;
diff--;
}
else if(lengthA<lengthB) while(diff>0){
headB=headB.next;
diff--;
}
if(headA.next==null) {
if(headA==headB) return headA;
else return null;
}
while(headA.next!=null){
if(headA==headB) return headA;
headA=headA.next;
headB=headB.next;
if(headA==headB) return headA;
}
return null;
}
代码过了,但是实现的太粗糙