题目描述
输入两个链表,找出它们的第一个公共结点。
有公共节点的两个链表在公共节点汇合后,后面的节点均相同,为Y型。
方法一:消除长度差后,两者到公共节点距离相同。时间复杂度O(m+n)。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
int getLength(ListNode* pHead)
{
int len = 0;
ListNode* p = pHead;
while(p != nullptr)
{
len ++;
p = p->next;
}
return len;
}
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1 == nullptr || pHead2 == nullptr)
return nullptr;
int len1 = getLength(pHead1);
int len2 = getLength(pHead2);
int lenDif = len1 - len2;
ListNode* pLong = pHead1;
ListNode* pShort = pHead2;
if(len1 < len2)
{
pLong = pHead2;
pShort = pHead1;
lenDif = len2 - len1;
}
for(int i = 0; i < lenDif; i++)
pLong = pLong->next;
while(pLong != nullptr && pShort != nullptr && pLong != pShort)
{
pLong = pLong->next;
pShort = pShort->next;
}
ListNode* pCommon = pLong;
return pCommon;
}
};
方法二:用两个指针分别遍历总链表,指针将在重合点或者末尾处相遇。时间复杂度O(m+n)。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
ListNode* p1 = pHead1;
ListNode* p2 = pHead2;
while(p1 != p2)
{
p1 = (p1 == nullptr ? pHead2 : p1->next);
p2 = (p2 == nullptr ? pHead1 : p2->next);
}
return p1;
}
};
方法三:利用辅助栈从链表尾部向前遍历,时间复杂度O(m+n),空间复杂度O(m+n)
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1 == nullptr || pHead2 == nullptr)
return nullptr;
stack<ListNode*> s1;
stack<ListNode*> s2;
ListNode* p1 = pHead1;
ListNode* p2 = pHead2;
while(p1 != nullptr)
{
s1.push(p1);
p1 = p1->next;
}
while(p2 != nullptr)
{
s2.push(p2);
p2 = p2->next;
}
ListNode* tmp;
if(s1.top() != s2.top())
return nullptr;
while(!s2.empty() && !s1.empty() && s1.top() == s2.top())
{
tmp = s1.top();
s1.pop();
s2.pop();
}
return tmp;
}
};