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.
题目要注意一点就是两条链表交叉或者说集合在一起了之后,是不会在分开的。的确是呀!单向链表怎么会再分开呢?如果分开的话,其岂不是一个节点会只指向两个不同的节点?这都不是单向链表了。想通了这点之后就会更加明白下面这个利用两个指针的算法的实现。
可以将A,B两个链表看做两部分,交叉前与交叉后。
交叉后的长度是一样的,因此交叉前的长度差即为总长度差。
只要去除这些长度差,距离交叉点就等距了。
为了节省计算,在计算链表长度的时候,顺便比较一下两个链表的尾节点是否一样,
若不一样,则不可能相交,直接可以返回NULL
public ListNode getIntersectionNode1(ListNode headA, ListNode headB) {
if (headA == null || headB == null) {
return null;
}
int lenA = getLen(headA);
int lenB = getLen(headB);
if (lenA > lenB) {
while (lenA > lenB) {
headA = headA.next;
lenA--;
}
} else {
while (lenA < lenB) {
headB = headB.next;
lenB--;
}
}
while (headA != null) {
if (headA == headB) {
return headA;
}
headA = headA.next;
headB = headB.next;
}
return null;
}
public int getLen(ListNode node) {
int len = 0;
while (node != null) {
len++;
node = node.next;
}
return len;
}
PS:Java内置de单向链表,功能应该更加强大,可以有封装好的函数直接返回单向链表的长度?
网友评论