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的時間複雜度爲
方法2:
- 求出兩個鏈表的長度m和n
- 根據鏈表的長度,用一先一後兩個指針在兩個鏈表上,開始遍歷。當兩個指針相等的時候,則此時指針指向的節點即爲:兩者的公共節點
方法2的時間複雜度爲
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;
}