题目:输入两个链表,找出它们的第一个公共结点。
解法一:利用环的思想。利用两个指针分别从头开始遍历两个链表,当遍历到一个链表的末尾时,跳到另外一个链表的头继续开始遍历。两个指针同步遍历,并且在遍历的过程中不断进行比较,当两个指针相等时,即为两个链表的第一个公共节点。
注:两个指针一定会有相等的时候,因为是同步遍历,最差的情况是:当两个指针都遍历了一遍两个链表时,两个指针所走的路程相等,如果到达这一步,像个指针都为空指针,两者相等,输出即可。如果在前面的遍历过程中出现相等,即为第一个公共节点,输出即可。
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if (pHead1==nullptr||pHead2==nullptr) return nullptr;
ListNode* l1 = pHead1;
ListNode* l2 = pHead2;
while(l1!=l2)
{
if(l1==nullptr) l1 =pHead2;
else l1 = l1->next;
if(l2==nullptr) l2 =pHead1;
else l2 = l2->next;
}
return l1;
}
};
解法二:
思路:比较两个链表的长度,让长的链表先走几步,使剩下的长度和短的链表长度相等,然后同步遍历即可。遇到指针相等的情况,即为答案。
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
ListNode* l1 = pHead1;
ListNode* l2 =pHead2;
int len1= 0,len2=0;
while(l1)
{
l1=l1->next;
++len1;
}
while(l2)
{
l2=l2->next;
++len2;
}
int diff = abs(len1-len2);
l1 = pHead1;
l2 =pHead2;
while(diff--)
{
if(len1>len2) l1=l1->next;
if(len2>len1) l2=l2->next;
}
while(l1!=l2)
{
l1=l1->next;
l2=l2->next;
}
return l1;
}
};
解法三:
思路:遍历两个链表,并依次把节点压入两个不同的栈中,然后逐步弹出,不相等的指针的下一个即为第一个公共节点。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};*/
class Solution {
public:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
stack<ListNode*> s1;
stack<ListNode*> s2;
ListNode* l1 =pHead1;
ListNode* l2 =pHead2;
while(l1)
{
s1.push(l1);
l1=l1->next;
}
while(l2)
{
s2.push(l2);
l2=l2->next;
}
while(!s1.empty()&&!s2.empty())
{
l1=s1.top();
l2=s2.top();
if(l1!=l2)
{
return l1->next;
}
s1.pop();
s2.pop();
}
if(s1.empty()&&s2.empty())
return pHead1;
if(s1.empty())
return s2.top()->next;
if(s2.empty())
return s1.top()->next;
return nullptr;
}
};