两个链表的第一个公共节点
输入两个链表,找出他们的第一个公共节点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式实现的,保证传入数据是正确的)
题解:
阵对这个题目有三种解法:
1)map法:
将第一个链表的所有节点都保存进入map中,然后然后对第二个链表进行查找,观察是否存在在map中,若存在,则输入该节点。
代码如下:
/*
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||!pHead2) return NULL;
map<ListNode*,int> mp;
while(pHead1){
mp[pHead1]=pHead1->val;
pHead1=pHead1->next;
}
while(pHead2){
if(mp.find(pHead2)!=mp.end())
break;
pHead2=pHead2->next;
}
return pHead2;
}
};
2)链表长度法:
如果两个链表有公共节点,那么其重合节点后的长度是一样的。
因此,可经历两次遍历,分别得到两个链表的长度。
比较二者的长短,对长的链表进行遍历,等长链表剩下的节点数与短链表的节点数相等时,同时进行遍历,比较两链表的节点是否相等。
代码如下:
/*
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||!pHead2) return NULL;
map<ListNode*,int> mp;
while(pHead1){
mp[pHead1]=pHead1->val;
pHead1=pHead1->next;
}
while(pHead2){
if(mp.find(pHead2)!=mp.end())
break;
pHead2=pHead2->next;
}
return pHead2;*/
if(!pHead1||!pHead2) return NULL;
int len1=0,len2=0;
ListNode *p,*q;
p=pHead1;q=pHead2;//用以遍历长度后,重新更新头节点
while(pHead1){//计算链表1的长度
len1++;
pHead1=pHead1->next;
}
while(pHead2){//链表2的长度
len2++;
pHead2=pHead2->next;
}
if(len1>len2){
int len=len1-len2;
for(int i=0;i<len;i++)
p=p->next;//遍历长链表长于短链表的节点
}
else{
int len=len2-len1;
for(int i=0;i<len;i++)
q=q->next;
}
while(p){//两个链表同时遍历节点
if(p==q)
return p;
q=q->next;
p=p->next;
}
return NULL;
}
};
3)双指针法:
假设链表1长度为a+n,链表2的长度为b+n(a>b)。利用两个指针同时遍历两个链表,当链表2遍历完后,链表1所处的节点位置为b+n,剩余节点为a-b。将遍历完链表2的指针指向1,需要走b+n+a。而指向a链表的指针遍历完a链表时,指向b的头节点,则走到相同节点,需要走a+b+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||!pHead2) return NULL;
map<ListNode*,int> mp;
while(pHead1){
mp[pHead1]=pHead1->val;
pHead1=pHead1->next;
}
while(pHead2){
if(mp.find(pHead2)!=mp.end())
break;
pHead2=pHead2->next;
}
return pHead2;*/
/*if(!pHead1||!pHead2) return NULL;
int len1=0,len2=0;
ListNode *p,*q;
p=pHead1;q=pHead2;
while(pHead1){
len1++;
pHead1=pHead1->next;
}
while(pHead2){
len2++;
pHead2=pHead2->next;
}
if(len1>len2){
int len=len1-len2;
for(int i=0;i<len;i++)
p=p->next;
}
else{
int len=len2-len1;
for(int i=0;i<len;i++)
q=q->next;
}
while(p){
if(p==q)
return p;
q=q->next;
p=p->next;
}
return NULL;*/
if(!pHead1||!pHead2) return NULL;
ListNode *p,*q;
p=pHead1;
q=pHead2;
while(p!=q){
if(p) p=p->next;
if(q) q=q->next;
if(p!=q){
if(!p) p=pHead2;
if(!q) q=pHead1;
}
}
return p;
}
};