题目描述
【leetcode】160. 相交链表( Intersection of Two Linked Lists )
编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:
在节点 c1 开始相交。
第一次解答
思路:
想象一下,若链表相交,链表A,B各自与其尾部相连,
成一个8字,各自从end节点出发,8字一圈,最终会在节点c1处相交。
这是因为链表A+B与链表B+A长度一致
精简代码。缺点是在不相交时一定要遍历完A+B的长度才能得到结果。
test case:
0
[1,3,5,7,9,11,13,15,17,19,21]
[2]
11
1
8
[4,1,8,4,5]
[5,0,1,8,4,5]
2
3
/**
* 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) {
if(nullptr == headA || nullptr == headB){
return nullptr;
}
ListNode *p_A = headA;
ListNode *p_B = headB;
ListNode *p_A_end = nullptr;
ListNode *p_B_end = nullptr;
while(true){
if(p_A == p_B){
return p_A;
}
if(nullptr == p_B->next){
p_B_end = p_B;
p_B = headA;
// 若链表相交为一个,则结尾将相同
if(nullptr != p_A_end && p_A_end != p_B_end){
return nullptr;
}
}
else{
p_B = p_B->next;
}
if(nullptr == p_A->next){
p_A_end = p_A;
p_A = headB;
// 若链表相交为一个,则结尾将相同
if(nullptr != p_B_end && p_A_end != p_B_end){
return nullptr;
}
}
else{
p_A = p_A->next;
}
}
return nullptr;
}
};
结果:
第二次解答
思路:
精简解答一的代码。缺点是在不相交时一定要遍历完A+B的长度才能得到结果。
/**
* 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) {
if(nullptr == headA || nullptr == headB){
return nullptr;
}
ListNode *p_A = headA;
ListNode *p_B = headB;
// 若不相交也不会无限循环,
// 因为拼接后A+B与B+A等长,第二次到结尾会同时为nullptr
while(p_A != p_B){
p_A = (p_A == nullptr ? headB : p_A->next);
p_B = (p_B == nullptr ? headA : p_B->next);
}
return p_A;
}
};
结果:
其他思路
- 利用哈希表。
- 从A和B最后一个元素往前遍历,若最后一个元素都不相同,则不相交;若最后若干个元素相同,直到某个元素不同,则那里的前一个元素为交点。可以利用stack实现这个过程。可参考官方题解和别人的题解