1.题目描述
输入两个链表,找出它们的第一个公共结点。
链表结构如下:
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) :
val(x), next(NULL) {
}
};
2.基本思路
设链表pHead1的长度为m,pHead2的长度为n.
方法1:
- 先遍历pHead1,将其中每一个节点都存储起来在一个hash表中
- 再从pHead2头节点开始遍历,边遍历边查询,第一次遇到的在hash表中存在的节点即为两个链表的公共节点的头节点,输出即可
方法1的时间复杂度为 O(m+n) ,空间复杂度为 O(m)
方法2:
- 求出两个链表的长度m和n
- 根据链表的长度,用一先一后两个指针在两个链表上,开始遍历。当两个指针相等的时候,则此时指针指向的节点即为:两者的公共节点
方法2的时间复杂度为 O(m+n) ,但是空间复杂度为 O(1)
3.代码如下
方法1:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1==NULL | pHead2==NULL){
return NULL;
}
ListNode *p=pHead1;
unordered_map<ListNode*,int> hash; // 用set等其他容器当然也可以
while(p!=NULL){
hash[p]=0;
p=p->next;
}
p=pHead2;
while(p!=NULL && hash.find(p)==hash.end()){
p=p->next;
}
return p;
}
方法2:
ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
if(pHead1==NULL || pHead2==NULL){
return NULL;
}
int m,n;
ListNode *p,*p1;
p=pHead1;
p1=pHead2;
m=0;
n=0;
while(p!=NULL){
++m;
p=p->next;
}
while(p1!=NULL){
++n;
p1=p1->next;
}
if(n<=m){
int i=0;
p=pHead1;
while(i < (m-n)){
p=p->next;
++i;
}
p1=pHead2;
}else{
int i=0;
p=pHead2;
while(i<(n-m)){
p=p->next;
++i;
}
p1=pHead1;
}
while(p!=p1){
p1=p1->next;
p=p->next;
}
return p;
}