一、题目描述
JZ36两个链表的第一个公共结点
题目大意:给定两个链表A和B,他们尾部的几个结点可能是相同的,我们需要返回第一个公共结点的指针
注意审题:两个链表也可以没有公共结点,此时返回空指针即可
二、算法1(双指针)
算法思路
1.总体思路:我们可以分别用两个指针指向链表的头结点,然后一步一步地向后移动,当两个指针指向相同的结点时,直接返回即可
2.但是注意一个问题,由于两链表的长度不一定是相同的,因此我们需要预处理一下,保证两指针的相对位置重合
3.实现方法:先计算一下两条链表的长度len1, len2;若len1 > len2,则p1指针向后移动len1 - len2步;若len1 < len2,则p2指针向后移动len2 - len1步;len1 = len2时不变;这样预处理就完成了,最后两指针再同步向后移动即可
代码实现(C++11)
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
int len1 = get_ListLength(pHead1);
int len2 = get_ListLength(pHead2);
ListNode *p1 = pHead1, *p2 = pHead2;
if(len1 > len2){
while(len1 > len2){
p1 = p1->next;
--len1;
}
}
if(len2 > len1){
while(len2 > len1){
p2 = p2->next;
--len2;
}
}
while(p1){
if(p1 == p2) return p1;
p1 = p1->next;
p2 = p2->next;
}
return p1;
}
int get_ListLength(ListNode* head){
int len = 0;
while(head){
head = head->next;
++len;
}
return len;
}
}; 时间复杂度:O(n + m), n和m分别是链表A,B的长度
空间复杂度:O(1)
三、算法2(哈希集合)
算法思路
1.总体思路:我们先将其中一条链表的所有结点存下来,再遍历另一条链表,若查找到了相同的结点,则直接返回;若遍历完了都没有找到,就返回空指针
代码实现(C++11)
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
unordered_set<ListNode*> s;
ListNode *p1 = pHead1, *p2 = pHead2;
while(p1){
s.insert(p1);
p1 = p1->next;
}
while(p2){
if(s.count(p2)) return p2;
p2 = p2->next;
}
return nullptr;
}
}; 时间复杂度:O(n + m), n和m分别是链表A,B的长度
空间复杂度:O(n)

京公网安备 11010502036488号