面試OR筆試21——兩個鏈表的第一個公共節點

題目及要求

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;
}






發佈了58 篇原創文章 · 獲贊 23 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章