1 題目及要求
1.1 題目描述
輸入兩個鏈表,找出他們的第一個公共節點。
2 解答
2.1 代碼
#include <iostream>
#include <stack>
using namespace std;
// 鏈表節點類
struct ListNode{
int val;
ListNode *next;
ListNode(int x = 0):val(x),next(nullptr){}
};
// 掃描 o(m*n)時間
ListNode* firstCommonNode1(ListNode *head1, ListNode *head2){
if(!(head1&&head2)) return nullptr;
for(ListNode* np;head1;head1 = head1->next)
for(np = head2;np;np = np->next)
if(np==head1) return np;
return nullptr;
}
// 棧實現,從尾到頭逐個比較,直到最後一個相同的 o(m+n)時間, o(m+n)空間
ListNode* firstCommonNode2(ListNode *head1, ListNode *head2){
if(!(head1&&head2)) return nullptr;
stack<ListNode*> st1,st2;
for(;head1;head1 = head1->next) st1.push(head1);
for(;head2;head2 = head2->next) st2.push(head2);
while(!(st1.empty() || st2.empty()) && st1.top()==st2.top()){
head1 = st1.top();
st1.pop();
st2.pop();
}
return head1;
}
// 循環實現, o(m+n)時間, o(1)空間
ListNode* firstCommonNode3(ListNode *head1, ListNode *head2){
if(!(head1&&head2)) return nullptr;
ListNode *np1 = head1, *np2 = head2;
while(np1!=np2){
np1 = np1 ? np1->next : head2;
np2 = np2 ? np2->next : head1;
}
return np1;
}
int main(){
ListNode h1[] = {1,2,3,4,5,6,7}, h2[] = {8,9};
int s1 = sizeof(h1)/sizeof(ListNode), s2 = sizeof(h2)/sizeof(ListNode);
for(int k1(0);k1<s1-1;++k1) h1[k1].next = h1+k1+1;
for(int k2(0);k2<s2-1;++k2) h2[k2].next = h2+k2+1;
// 這裏從第5個節點(val = 5)開始公用節點
h2[s2-1].next = h1+4;
auto np1 = firstCommonNode1(h1,h2);
auto np2 = firstCommonNode2(h1,h2);
auto np3 = firstCommonNode3(h1,h2);
cout << (np1?np1->val:0) << endl;
cout << (np2?np2->val:0) << endl;
cout << (np3?np3->val:0) << endl;
return 0;
}