编写一个程序,找到两个单链表相交的起始节点。
例如,下面的两个链表:
A: a1 → a2
↘
c1 → c2 → c3
↗
B: b1 → b2 → b3
在节点 c1 开始相交。
注意:
如果两个链表没有交点,返回 null.
在返回结果后,两个链表仍须保持原有的结构。
可假定整个链表结构中没有循环。
程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。
这个题如果使用暴力循环的话复杂度就会很高,可能会达到O(
),所以这个方法不可取。换一种思路,链表其实只有后面的会相交,所以如果两个链表长度相同的话,直接遍历到两个指针相同即可,如果长度不同,那就直接把长链表前面多的部分截掉,然后一起遍历到两个指针长度相同,这样永远只需要两次循环即可。第一次遍历获得两个链表的长度,第二次截掉前面多余的然后寻找相交点。
C++源代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode *pA = headA;
ListNode *pB = headB;
int lenA = 0, lenB = 0;
while(pA!=NULL || pB!=NULL){
if (pA!=NULL){
lenA++;
pA = pA->next;
}
if (pB!=NULL){
lenB++;
pB = pB->next;
}
}
pA = headA;
pB = headB;
if (lenA>lenB){
int diff = lenA - lenB;
while(diff--)
pA = pA->next;
}
if(lenB>lenA){
int diff = lenB - lenA;
while(diff--)
pB = pB->next;
}
while(pA!=pB){
pA = pA->next;
pB = pB->next;
}
return pA;
}
};
python3源代码:
# Definition for singly-linked list.
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def getIntersectionNode(self, headA, headB):
"""
:type head1, head1: ListNode
:rtype: ListNode
"""
pA = headA
pB = headB
lenA = 0
lenB = 0
while pA!=None or pB!=None:
if pA!=None:
lenA += 1
pA = pA.next
if pB!=None:
lenB += 1
pB = pB.next
pA = headA
pB = headB
if lenA > lenB:
diff = lenA - lenB
while diff:
pA = pA.next
diff -= 1
if lenB > lenA:
diff = lenB - lenA
while diff:
pB = pB.next
diff -= 1
while pA!=pB:
pA = pA.next
pB = pB.next
return pA