剑指offer36:两个链表的第一个公共结点
1 题目描述
输入两个链表,找出它们的第一个公共结点。
2 思路和方法
方法一:
用两个指针同时从两个链表的表头开始走,当走到自己的链表结尾的时候开始从另一个链表的表头开始向后走。终止条件就是两个指针第一次相遇。此时指针位置即为所求。(两个链表的节点和是一定的,所以两个指针一定可以同时遍历完两条链表,即在最后时刻两个指针一定是重合的)
方法2:
先数出两条链表的长度,得到长度差d,先将长链表从头结点往后走d步,之后第二个链表从头开始,两个链表一起一步一步走,直到两个链表的节点第一次相等为止,此时指针位置即为所求。
3 C++核心代码
1 ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2) { 2 ListNode *p1 = pHead1; 3 ListNode *p2 = pHead2; 4 while(p1!=p2){ 5 p1 = (p1==NULL ? pHead2 : p1->next); 6 p2 = (p2==NULL ? pHead1 : p2->next); 7 } 8 return p1; 9 }
1 ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) { 2 ListNode *p1=pHead1; 3 ListNode *p2=pHead2; 4 int len1=0,len2=0,diff=0; 5 while(p1!=NULL){ 6 p1=p1->next; 7 len1++; 8 } 9 while(p2!=NULL){ 10 p2=p2->next; 11 len2++; 12 } 13 if(len1>len2){ 14 diff=len1-len2; 15 p1=pHead1; 16 p2=pHead2; 17 } 18 else{ 19 diff=len2-len1; 20 p1=pHead2; 21 p2=pHead1; 22 } 23 for(int i=0;i<diff;i++){ 24 p1=p1->next; 25 } 26 while(p1!=NULL && p2!=NULL){ 27 if(p1==p2) 28 break; 29 p1=p1->next; 30 p2=p2->next; 31 } 32 return p1; 33 }
4 C++完整代码
1 #include<iostream> 2 using namespace std; 3 4 struct ListNode 5 { 6 int m_nValue; 7 ListNode* m_pNext; 8 }; 9 10 //创建链表节点 11 ListNode* CreateListNode(int value) 12 { 13 ListNode* pNode = new ListNode(); 14 pNode->m_nValue = value; 15 pNode->m_pNext = NULL; 16 17 return pNode; 18 } 19 20 21 //连接链表节点 22 void ConnectListNodes(ListNode* pCurrent, ListNode* pNext) 23 { 24 if (pCurrent == NULL) 25 { 26 //exit(1),非正常运行导致退出程序;exit(0),正常运行并退出程序 27 cout << "Error to connect two nodes." << endl; 28 exit(1); 29 } 30 31 pCurrent->m_pNext = pNext; 32 } 33 34 35 //销毁链表 36 void DestroyList(ListNode* pHead) 37 { 38 ListNode* pNode = pHead; 39 40 while (pNode!=NULL) 41 { 42 pHead = pHead->m_pNext; 43 delete pNode; 44 pNode = pHead; 45 } 46 } 47 48 //销毁节点 49 void DestroyNode(ListNode* pNode) 50 { 51 delete pNode; 52 pNode = NULL; 53 } 54 55 //求链表的长度 56 unsigned int GetListLength(ListNode* pHead) 57 { 58 unsigned int nLength = 0; 59 ListNode* pNode = pHead; 60 61 while (pNode!=NULL) 62 { 63 nLength++; 64 pNode = pNode->m_pNext; 65 } 66 67 return nLength; 68 } 69 70 //找第一个公共节点 71 ListNode* FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2) 72 { 73 //求两个链表的长度 74 unsigned int nLength1 = GetListLength(pHead1); 75 unsigned int nLength2 = GetListLength(pHead2); 76 //两个链表的长度差 77 int nLengthDif = nLength1 - nLength2; 78 ListNode* pListHeadLong = pHead1; 79 ListNode* pListHeadShort= pHead2; 80 if (nLength2 > nLength1) 81 { 82 pListHeadLong = pHead2; 83 pListHeadShort = pHead1; 84 nLengthDif = nLength2 - nLength1; 85 } 86 87 // 先在长链表上走几步,再同时在两个链表上遍历 88 for (int i = 0; i < nLengthDif; i++) 89 { 90 pListHeadLong = pListHeadLong->m_pNext; 91 } 92 93 while ((pListHeadLong!=NULL)&& (pListHeadShort != NULL)&&(pListHeadLong != pListHeadShort)) 94 { 95 pListHeadLong = pListHeadLong->m_pNext; 96 pListHeadShort = pListHeadShort->m_pNext; 97 } 98 99 //得到第一个公共节点 100 ListNode* pFisrtCommonNode = pListHeadLong; 101 //ListNode* pFisrtCommonNode = pListHeadShort;也可以 102 103 return pFisrtCommonNode; 104 } 105 106 107 // ====================测试代码==================== 108 void Test(char* testName, ListNode* pHead1, ListNode* pHead2, ListNode* pExpected) 109 { 110 if (testName != NULL) 111 { 112 cout << testName << " begins: "; 113 } 114 115 ListNode* pResult = FindFirstCommonNode(pHead1, pHead2); 116 if (pResult == pExpected) 117 { 118 cout << "Succeed!" << endl; 119 } 120 else 121 { 122 cout << "Failed!" << endl; 123 } 124 } 125 126 127 // 第一个公共结点在链表中间 128 // 1 - 2 - 3 \ 129 // 6 - 7 130 // 4 - 5 / 131 void Test1() 132 { 133 ListNode* pNode1 = CreateListNode(1); 134 ListNode* pNode2 = CreateListNode(2); 135 ListNode* pNode3 = CreateListNode(3); 136 ListNode* pNode4 = CreateListNode(4); 137 ListNode* pNode5 = CreateListNode(5); 138 ListNode* pNode6 = CreateListNode(6); 139 ListNode* pNode7 = CreateListNode(7); 140 141 ConnectListNodes(pNode1, pNode2); 142 ConnectListNodes(pNode2, pNode3); 143 ConnectListNodes(pNode3, pNode6); 144 ConnectListNodes(pNode4, pNode5); 145 ConnectListNodes(pNode5, pNode6); 146 ConnectListNodes(pNode6, pNode7); 147 148 Test("Test1", pNode1, pNode4, pNode6); 149 150 DestroyNode(pNode1); 151 DestroyNode(pNode2); 152 DestroyNode(pNode3); 153 DestroyNode(pNode4); 154 DestroyNode(pNode5); 155 DestroyNode(pNode6); 156 DestroyNode(pNode7); 157 } 158 159 // 没有公共结点 160 // 1 - 2 - 3 - 4 161 // 162 // 5 - 6 - 7 163 void Test2() 164 { 165 ListNode* pNode1 = CreateListNode(1); 166 ListNode* pNode2 = CreateListNode(2); 167 ListNode* pNode3 = CreateListNode(3); 168 ListNode* pNode4 = CreateListNode(4); 169 ListNode* pNode5 = CreateListNode(5); 170 ListNode* pNode6 = CreateListNode(6); 171 ListNode* pNode7 = CreateListNode(7); 172 173 ConnectListNodes(pNode1, pNode2); 174 ConnectListNodes(pNode2, pNode3); 175 ConnectListNodes(pNode3, pNode4); 176 ConnectListNodes(pNode5, pNode6); 177 ConnectListNodes(pNode6, pNode7); 178 179 Test("Test2", pNode1, pNode5, NULL); 180 181 DestroyList(pNode1); 182 DestroyList(pNode5); 183 } 184 185 // 公共结点是最后一个结点 186 // 1 - 2 - 3 - 4 \ 187 // 7 188 // 5 - 6 / 189 void Test3() 190 { 191 ListNode* pNode1 = CreateListNode(1); 192 ListNode* pNode2 = CreateListNode(2); 193 ListNode* pNode3 = CreateListNode(3); 194 ListNode* pNode4 = CreateListNode(4); 195 ListNode* pNode5 = CreateListNode(5); 196 ListNode* pNode6 = CreateListNode(6); 197 ListNode* pNode7 = CreateListNode(7); 198 199 ConnectListNodes(pNode1, pNode2); 200 ConnectListNodes(pNode2, pNode3); 201 ConnectListNodes(pNode3, pNode4); 202 ConnectListNodes(pNode4, pNode7); 203 ConnectListNodes(pNode5, pNode6); 204 ConnectListNodes(pNode6, pNode7); 205 206 Test("Test3", pNode1, pNode5, pNode7); 207 208 DestroyNode(pNode1); 209 DestroyNode(pNode2); 210 DestroyNode(pNode3); 211 DestroyNode(pNode4); 212 DestroyNode(pNode5); 213 DestroyNode(pNode6); 214 DestroyNode(pNode7); 215 } 216 217 // 公共结点是第一个结点 218 // 1 - 2 - 3 - 4 - 5 219 // 两个链表完全重合 220 void Test4() 221 { 222 ListNode* pNode1 = CreateListNode(1); 223 ListNode* pNode2 = CreateListNode(2); 224 ListNode* pNode3 = CreateListNode(3); 225 ListNode* pNode4 = CreateListNode(4); 226 ListNode* pNode5 = CreateListNode(5); 227 228 ConnectListNodes(pNode1, pNode2); 229 ConnectListNodes(pNode2, pNode3); 230 ConnectListNodes(pNode3, pNode4); 231 ConnectListNodes(pNode4, pNode5); 232 233 Test("Test4", pNode1, pNode1, pNode1); 234 235 DestroyList(pNode1); 236 } 237 238 // 输入的两个链表有一个空链表 239 void Test5() 240 { 241 ListNode* pNode1 = CreateListNode(1); 242 ListNode* pNode2 = CreateListNode(2); 243 ListNode* pNode3 = CreateListNode(3); 244 ListNode* pNode4 = CreateListNode(4); 245 ListNode* pNode5 = CreateListNode(5); 246 247 ConnectListNodes(pNode1, pNode2); 248 ConnectListNodes(pNode2, pNode3); 249 ConnectListNodes(pNode3, pNode4); 250 ConnectListNodes(pNode4, pNode5); 251 252 Test("Test5", NULL, pNode1, NULL); 253 254 DestroyList(pNode1); 255 } 256 257 // 输入的两个链表都是空链表 258 void Test6() 259 { 260 Test("Test6", NULL, NULL, NULL); 261 } 262 263 264 int main() 265 { 266 Test1(); 267 Test2(); 268 Test3(); 269 Test4(); 270 Test5(); 271 Test6(); 272 system("pause"); 273 return 0; 274 }
参考资料
https://blog.csdn.net/lingfeng2019/article/details/80778598
https://blog.csdn.net/yanxiaolx/article/category/6250534(完整代码)