剑指offer第三十七题:两个链表的第一个公共结点
1 //============================================================================ 2 // Name : JZ-C-37.cpp 3 // Author : Laughing_Lz 4 // Version : 5 // Copyright : All Right Reserved 6 // Description : 两个链表的第一个公共结点 7 //============================================================================ 8 9 #include <iostream> 10 #include <stdio.h> 11 #include "List.h" 12 using namespace std; 13 14 unsigned int GetListLength(ListNode* pHead); 15 /** 16 * 先移动长链表指针至某位置(与短链表持平),再同时遍历,遇到第一个相同的结点即为公共结点 17 * 时间复杂度为O(m+n) 18 */ 19 ListNode* FindFirstCommonNode(ListNode *pHead1, ListNode *pHead2) { 20 // 得到两个链表的长度 21 unsigned int nLength1 = GetListLength(pHead1); 22 unsigned int nLength2 = GetListLength(pHead2); 23 int nLengthDif = nLength1 - nLength2; 24 25 ListNode* pListHeadLong = pHead1; 26 ListNode* pListHeadShort = pHead2; 27 if (nLength2 > nLength1) { 28 pListHeadLong = pHead2; 29 pListHeadShort = pHead1; 30 nLengthDif = nLength2 - nLength1; 31 } 32 33 // 先在长链表上走几步,再同时在两个链表上遍历 34 for (int i = 0; i < nLengthDif; ++i) 35 pListHeadLong = pListHeadLong->m_pNext; 36 37 while ((pListHeadLong != NULL) && (pListHeadShort != NULL) 38 && (pListHeadLong != pListHeadShort)) { 39 pListHeadLong = pListHeadLong->m_pNext;//当不存在公共结点时,返回NULL 40 pListHeadShort = pListHeadShort->m_pNext; 41 } 42 43 // 得到第一个公共结点 44 ListNode* pFisrtCommonNode = pListHeadLong; 45 46 return pFisrtCommonNode; 47 } 48 49 unsigned int GetListLength(ListNode* pHead) { 50 unsigned int nLength = 0; 51 ListNode* pNode = pHead; 52 while (pNode != NULL) { 53 ++nLength; 54 pNode = pNode->m_pNext; 55 } 56 57 return nLength; 58 } 59 60 // ====================测试代码==================== 61 void DestroyNode(ListNode* pNode); 62 63 void Test(char* testName, ListNode* pHead1, ListNode* pHead2, 64 ListNode* pExpected) { 65 if (testName != NULL) 66 printf("%s begins: ", testName); 67 68 ListNode* pResult = FindFirstCommonNode(pHead1, pHead2); 69 if (pResult == pExpected) 70 printf("Passed. "); 71 else 72 printf("Failed. "); 73 } 74 75 // 第一个公共结点在链表中间 76 // 1 - 2 - 3 77 // 6 - 7 78 // 4 - 5 / 79 void Test1() { 80 ListNode* pNode1 = CreateListNode(1); 81 ListNode* pNode2 = CreateListNode(2); 82 ListNode* pNode3 = CreateListNode(3); 83 ListNode* pNode4 = CreateListNode(4); 84 ListNode* pNode5 = CreateListNode(5); 85 ListNode* pNode6 = CreateListNode(6); 86 ListNode* pNode7 = CreateListNode(7); 87 88 ConnectListNodes(pNode1, pNode2); 89 ConnectListNodes(pNode2, pNode3); 90 ConnectListNodes(pNode3, pNode6); 91 ConnectListNodes(pNode4, pNode5); 92 ConnectListNodes(pNode5, pNode6); 93 ConnectListNodes(pNode6, pNode7); 94 95 Test("Test1", pNode1, pNode4, pNode6); 96 97 DestroyNode(pNode1); 98 DestroyNode(pNode2); 99 DestroyNode(pNode3); 100 DestroyNode(pNode4); 101 DestroyNode(pNode5); 102 DestroyNode(pNode6); 103 DestroyNode(pNode7); 104 } 105 106 // 没有公共结点 107 // 1 - 2 - 3 - 4 108 // 109 // 5 - 6 - 7 110 void Test2() { 111 ListNode* pNode1 = CreateListNode(1); 112 ListNode* pNode2 = CreateListNode(2); 113 ListNode* pNode3 = CreateListNode(3); 114 ListNode* pNode4 = CreateListNode(4); 115 ListNode* pNode5 = CreateListNode(5); 116 ListNode* pNode6 = CreateListNode(6); 117 ListNode* pNode7 = CreateListNode(7); 118 119 ConnectListNodes(pNode1, pNode2); 120 ConnectListNodes(pNode2, pNode3); 121 ConnectListNodes(pNode3, pNode4); 122 ConnectListNodes(pNode5, pNode6); 123 ConnectListNodes(pNode6, pNode7); 124 125 Test("Test2", pNode1, pNode5, NULL); 126 127 DestroyList(pNode1); 128 DestroyList(pNode5); 129 } 130 131 // 公共结点是最后一个结点 132 // 1 - 2 - 3 - 4 133 // 7 134 // 5 - 6 / 135 void Test3() { 136 ListNode* pNode1 = CreateListNode(1); 137 ListNode* pNode2 = CreateListNode(2); 138 ListNode* pNode3 = CreateListNode(3); 139 ListNode* pNode4 = CreateListNode(4); 140 ListNode* pNode5 = CreateListNode(5); 141 ListNode* pNode6 = CreateListNode(6); 142 ListNode* pNode7 = CreateListNode(7); 143 144 ConnectListNodes(pNode1, pNode2); 145 ConnectListNodes(pNode2, pNode3); 146 ConnectListNodes(pNode3, pNode4); 147 ConnectListNodes(pNode4, pNode7); 148 ConnectListNodes(pNode5, pNode6); 149 ConnectListNodes(pNode6, pNode7); 150 151 Test("Test3", pNode1, pNode5, pNode7); 152 153 DestroyNode(pNode1); 154 DestroyNode(pNode2); 155 DestroyNode(pNode3); 156 DestroyNode(pNode4); 157 DestroyNode(pNode5); 158 DestroyNode(pNode6); 159 DestroyNode(pNode7); 160 } 161 162 // 公共结点是第一个结点 163 // 1 - 2 - 3 - 4 - 5 164 // 两个链表完全重合 165 void Test4() { 166 ListNode* pNode1 = CreateListNode(1); 167 ListNode* pNode2 = CreateListNode(2); 168 ListNode* pNode3 = CreateListNode(3); 169 ListNode* pNode4 = CreateListNode(4); 170 ListNode* pNode5 = CreateListNode(5); 171 172 ConnectListNodes(pNode1, pNode2); 173 ConnectListNodes(pNode2, pNode3); 174 ConnectListNodes(pNode3, pNode4); 175 ConnectListNodes(pNode4, pNode5); 176 177 Test("Test4", pNode1, pNode1, pNode1); 178 179 DestroyList(pNode1); 180 } 181 182 // 输入的两个链表有一个空链表 183 void Test5() { 184 ListNode* pNode1 = CreateListNode(1); 185 ListNode* pNode2 = CreateListNode(2); 186 ListNode* pNode3 = CreateListNode(3); 187 ListNode* pNode4 = CreateListNode(4); 188 ListNode* pNode5 = CreateListNode(5); 189 190 ConnectListNodes(pNode1, pNode2); 191 ConnectListNodes(pNode2, pNode3); 192 ConnectListNodes(pNode3, pNode4); 193 ConnectListNodes(pNode4, pNode5); 194 195 Test("Test5", NULL, pNode1, NULL); 196 197 DestroyList(pNode1); 198 } 199 200 // 输入的两个链表有一个空链表 201 void Test6() { 202 Test("Test6", NULL, NULL, NULL); 203 } 204 205 void DestroyNode(ListNode* pNode) { 206 delete pNode; 207 pNode = NULL; 208 } 209 210 int main(int argc, char** argv) { 211 Test1(); 212 Test2(); 213 Test3(); 214 Test4(); 215 Test5(); 216 Test6(); 217 218 return 0; 219 }