題目描述:
輸入兩個無環的單向鏈表,找出它們的第一個公共結點,如果沒有公共節點則返回空。(注意因為傳入數據是鏈表,所以錯誤測試數據的提示是用其他方式顯示的,保證傳入數據是正確的)
數據范圍: n<=1000
要求:空間復雜度 O(1),時間復雜度 O(n)
例如,輸入{1,2,3},{4,5},{6,7}時,兩個無環的單向鏈表的結構如下圖所示:
可以看到它們的第一個公共結點的結點值為6,所以返回結點值為6的結點。
輸入描述:
輸入分為是3段,第一段是第一個鏈表的非公共部分,第二段是第二個鏈表的非公共部分,第三段是第一個鏈表和二個鏈表的公共部分。 后臺會將這3個參數組裝為兩個鏈表,并將這兩個鏈表對應的頭節點傳入到函數FindFirstCommonNode里面,用戶得到的輸入只有pHead1和pHead2。
返回值描述:
返回傳入的pHead1和pHead2的第一個公共結點,后臺會打印以該節點為頭節點的鏈表。
示例:
輸入:
{1,2,3},{4,5},{6,7}
返回值:
{6,7}
說明:
第一個參數{1,2,3}代表是第一個鏈表非公共部分,第二個參數{4,5}代表是第二個鏈表非公共部分,最后的{6,7}表示的是2個鏈表的公共部分
這3個參數最后在后臺會組裝成為2個兩個無環的單鏈表,且是有公共節點的
解題思路:
本題考察數據結構鏈表的使用。將兩個鏈表指針向前步進,走到頭后就錯位繼續前進,因為兩個指針行進的速度一致,走著走著就撞一起了,如下方gif動畫所示,很直觀。
測試代碼:
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) { ListNode *a=pHead1,*b=pHead2; while(a!=b) { a=a?a->next:pHead2; b=b?b->next:pHead1; } return a; } };
補充
通過C++找出兩個鏈表的所有公共結點:
// FindFirstCommandNode.cpp : 定義控制臺應用程序的入口點。 // #include "stdafx.h" #include <iostream> using namespace std; struct ListNode { int m_nKey; ListNode* m_pNext; ListNode(int i):m_nKey(i) { } }; //獲取鏈表長度 int GetListLength(ListNode* pHead) { int nLength = 0; ListNode* pNode = pHead; while (pNode != NULL) { ++nLength; pNode = pNode->m_pNext; } return nLength; } ListNode* FindFirstCommandNode(ListNode* pHead1, ListNode* pHead2) { int nLength1 = GetListLength(pHead1); int nLength2 = GetListLength(pHead2); int nLengthDif = 0;//兩個鏈表的長度差 ListNode* pListHeadLong = NULL;//用于指向長鏈表 ListNode* pListHeadShort = NULL;//用于指向短鏈表 //根據長度判斷 鏈表指向 if (nLength1 > nLength2) { nLengthDif = nLength1 - nLength2; pListHeadShort = pHead2; pListHeadLong = pHead1; } else { nLengthDif = nLength2 - nLength1; pListHeadLong = pHead2; pListHeadShort = pHead1; } //先對長鏈表進行移動 移動到與短鏈表長度相同的位置 for (int i = 0; i < nLengthDif; i++) { pListHeadLong = pListHeadLong->m_pNext; } //尋找公共節點 while (pListHeadLong !=NULL && pListHeadShort != NULL && pListHeadLong!= pListHeadShort) { pListHeadLong = pListHeadLong->m_pNext; pListHeadShort = pListHeadShort->m_pNext; } //如果不為空 此時的pListHeadLong 與pListNodeShort為同一個節點,返回該節點 if (pListHeadLong != NULL) { return pListHeadLong; } else { return NULL;//否則返回NULL } } int _tmain(int argc, _TCHAR* argv[]) { ListNode* head1 = new ListNode(0); ListNode* head2 = new ListNode(1); ListNode* node0 = new ListNode(22); ListNode* node1 = new ListNode(2); ListNode* node2 = new ListNode(3); ListNode* node3 = new ListNode(4); ListNode* node4 = new ListNode(5); ListNode* node5 = new ListNode(6); ListNode* node6 = new ListNode(7); ListNode* node8 = new ListNode(6); head1->m_pNext = node1; node1->m_pNext = node0; node0->m_pNext = node3; node3->m_pNext = node5; node5->m_pNext = node6; node6->m_pNext = NULL; head2->m_pNext = node2; node2->m_pNext = node4; node4->m_pNext = node8; node8->m_pNext = node6; node6->m_pNext = NULL; cout<<"鏈表1的長度為:"<<GetListLength(head1)<<endl; cout<<"鏈表2的長度為:"<<GetListLength(head2)<<endl; ListNode* CommNode = FindFirstCommandNode(head1,head2); if (CommNode!= NULL) { cout<<"公共節點的值為:"<<CommNode->m_nKey<<endl; } else { cout<<"沒有公共節點"<<endl; } getchar(); return 0; }
到此這篇關于C++ 解決求兩個鏈表的第一個公共結點問題的文章就介紹到這了,更多相關C++ 求兩個鏈表的公共結點內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/zhaitianbao/article/details/121769106