-
题目:
输入两个链表,找出它们的第一个公共结点。(注意因为传入数据是链表,所以错误测试数据的提示是用其他方式显示的,保证传入数据是正确的) -
暴力解法,时间复杂度为(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;
ListNode* p1=pHead1,*p2=pHead2;
while(p1!=nullptr && p2!=nullptr)
{
while(p2!=nullptr)
{
if(p1==p2)
return p1;
else
p2=p2->next;
}
p1=p1->next;
p2=pHead2;
}
return nullptr;
}
};
- 好方法:时间复杂度为O(m+n);没有相同节点时,p1和p2分别将来两个链表都遍历一次;
如该两个链表有相同的节点,那么它们会一起从相同节点走到末尾;
a->b->1->d->nullptr;
2->1->d->nullptr;
/*
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;
ListNode* p1=pHead1,*p2=pHead2;
while(p1!=p2) //循环终止条件,有相同节点时,p1指向相同节点,没有时p1和p2都指向空;
{
p1=p1->next;
p2=p2->next;
if(p1 != p2)
{
if(p1==nullptr) p1=pHead2;
if(p2==nullptr) p2=pHead1;
}
}
return p1;
}
};
- 测试代码:
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<sstream>
#include<cmath>
#include<unordered_map>
using namespace std;
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;
ListNode* p1=pHead1,*p2=pHead2;
int count=0;
while(p1!=p2)
{
count++;
p1=p1->next;
p2=p2->next;
if(p1 != p2)
{
if(p1==nullptr)
p1=pHead2;
if(p2==nullptr) //1 2 3 4 5 6 7 8 9 p1
p2=pHead1; //1 3 6 7 8 9 p2
}
}
cout<<"while run "<<count<<endl;
return p1;
}
int CountNode(ListNode* head)
{
int i=0;
if(head==nullptr)
return i;
ListNode *p=head;
while(p!=nullptr)
{
i++;
p=p->next;
}
return i;
}
};
int main()
{
ListNode *pHead1=new ListNode(1);
ListNode *pHead2=new ListNode(2);
ListNode *pHead3=new ListNode(3);
ListNode *p1=pHead1,*p2=pHead2,*p3=pHead3;
for(int i=3;i<12;i++)
{
ListNode *p=new ListNode(i);
p1->next=p;
if(i>=5)
{
p3->next=p;
p3=p3->next;
}
p1=p1->next;
}
for(int i=5;i<8;i++)
{
ListNode *p=new ListNode(i);
p2->next=p;
p2=p2->next;
}
Solution sol;
int c1=sol.CountNode(pHead1);
int c2=sol.CountNode(pHead2);
int c3=sol.CountNode(pHead3);
cout<<"c1 node count is "<<c1<<endl;
cout<<"c2 node count is "<<c2<<endl;
cout<<"c3 node count is "<<c3<<endl;
ListNode *result2=sol.FindFirstCommonNode(pHead1,pHead2);
ListNode *result3=sol.FindFirstCommonNode(pHead1,pHead3);
//cout<<result->val<<endl;
if(result2==nullptr)
cout<<"result2:is nullptr"<<endl;
else
{
cout<<"result2 same node val is "<<result2->val<<endl;
}
if(result3==nullptr)
cout<<"result3: is nullptr"<<endl;
else
{
cout<<"result3 same node val is "<<result3->val<<endl;
}
}