《剑指offer》第十八题II:删除链表中重复的结点
// 面试题18(二):删除链表中重复的结点 // 题目:在一个排序的链表中,如何删除重复的结点?例如,在图3.4(a)中重复 // 结点被删除之后,链表如图3.4(b)所示。 #include <cstdio> #include "list.h" void DeleteDuplication(ListNode** pHead) //可能需要修改头指针 { if (pHead == nullptr || *pHead == nullptr) return; ListNode* pNodePre = nullptr; //待删除节点的前一个节点 ListNode* pNode = *pHead; while (pNode != nullptr) { ListNode* pNext = pNode->m_pNext; //当前节点的下一节点 bool needDelete = false; //标志位 if (pNext != nullptr && pNode->m_nValue == pNext->m_nValue) needDelete = true; //无重复 if (!needDelete) { pNodePre = pNode; pNode = pNode->m_pNext; } //有重复 else { int value = pNode->m_nValue; //重复的data ListNode* pToBeDel = pNode; //只要重复就一直删除 while (pToBeDel != nullptr && pToBeDel->m_nValue == value) { pNext = pToBeDel->m_pNext; //记录链表删除后部的指针 delete pToBeDel; pToBeDel = nullptr; pToBeDel = pNext; } if (pNodePre == nullptr) //要是前一节点为空, 设置其下一节点为头节点 *pHead = pNext; else //否则,连接前后链表 pNodePre->m_pNext = pNext; pNode = pNext; } } }
// ====================测试代码==================== void Test(const char* testName, ListNode** pHead, int* expectedValues, int expectedLength) { if (testName != nullptr) printf("%s begins: ", testName); DeleteDuplication(pHead); int index = 0; ListNode* pNode = *pHead; while (pNode != nullptr && index < expectedLength) { if (pNode->m_nValue != expectedValues[index]) break; pNode = pNode->m_pNext; index++; } if (pNode == nullptr && index == expectedLength) printf("Passed.\n"); else printf("FAILED.\n"); } // 某些结点是重复的 void Test1() { ListNode* pNode1 = CreateListNode(1); ListNode* pNode2 = CreateListNode(2); ListNode* pNode3 = CreateListNode(3); ListNode* pNode4 = CreateListNode(3); ListNode* pNode5 = CreateListNode(4); ListNode* pNode6 = CreateListNode(4); ListNode* pNode7 = CreateListNode(5); ConnectListNodes(pNode1, pNode2); ConnectListNodes(pNode2, pNode3); ConnectListNodes(pNode3, pNode4); ConnectListNodes(pNode4, pNode5); ConnectListNodes(pNode5, pNode6); ConnectListNodes(pNode6, pNode7); ListNode* pHead = pNode1; int expectedValues[] = { 1, 2, 5 }; Test("Test1", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int)); DestroyList(pHead); } // 没有重复的结点 void Test2() { ListNode* pNode1 = CreateListNode(1); ListNode* pNode2 = CreateListNode(2); ListNode* pNode3 = CreateListNode(3); ListNode* pNode4 = CreateListNode(4); ListNode* pNode5 = CreateListNode(5); ListNode* pNode6 = CreateListNode(6); ListNode* pNode7 = CreateListNode(7); ConnectListNodes(pNode1, pNode2); ConnectListNodes(pNode2, pNode3); ConnectListNodes(pNode3, pNode4); ConnectListNodes(pNode4, pNode5); ConnectListNodes(pNode5, pNode6); ConnectListNodes(pNode6, pNode7); ListNode* pHead = pNode1; int expectedValues[] = { 1, 2, 3, 4, 5, 6, 7 }; Test("Test2", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int)); DestroyList(pHead); } // 除了一个结点之外其他所有结点的值都相同 void Test3() { ListNode* pNode1 = CreateListNode(1); ListNode* pNode2 = CreateListNode(1); ListNode* pNode3 = CreateListNode(1); ListNode* pNode4 = CreateListNode(1); ListNode* pNode5 = CreateListNode(1); ListNode* pNode6 = CreateListNode(1); ListNode* pNode7 = CreateListNode(2); ConnectListNodes(pNode1, pNode2); ConnectListNodes(pNode2, pNode3); ConnectListNodes(pNode3, pNode4); ConnectListNodes(pNode4, pNode5); ConnectListNodes(pNode5, pNode6); ConnectListNodes(pNode6, pNode7); ListNode* pHead = pNode1; int expectedValues[] = { 2 }; Test("Test3", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int)); DestroyList(pHead); } // 所有结点的值都相同 void Test4() { ListNode* pNode1 = CreateListNode(1); ListNode* pNode2 = CreateListNode(1); ListNode* pNode3 = CreateListNode(1); ListNode* pNode4 = CreateListNode(1); ListNode* pNode5 = CreateListNode(1); ListNode* pNode6 = CreateListNode(1); ListNode* pNode7 = CreateListNode(1); ConnectListNodes(pNode1, pNode2); ConnectListNodes(pNode2, pNode3); ConnectListNodes(pNode3, pNode4); ConnectListNodes(pNode4, pNode5); ConnectListNodes(pNode5, pNode6); ConnectListNodes(pNode6, pNode7); ListNode* pHead = pNode1; Test("Test4", &pHead, nullptr, 0); DestroyList(pHead); } // 所有结点都成对出现 void Test5() { ListNode* pNode1 = CreateListNode(1); ListNode* pNode2 = CreateListNode(1); ListNode* pNode3 = CreateListNode(2); ListNode* pNode4 = CreateListNode(2); ListNode* pNode5 = CreateListNode(3); ListNode* pNode6 = CreateListNode(3); ListNode* pNode7 = CreateListNode(4); ListNode* pNode8 = CreateListNode(4); ConnectListNodes(pNode1, pNode2); ConnectListNodes(pNode2, pNode3); ConnectListNodes(pNode3, pNode4); ConnectListNodes(pNode4, pNode5); ConnectListNodes(pNode5, pNode6); ConnectListNodes(pNode6, pNode7); ConnectListNodes(pNode7, pNode8); ListNode* pHead = pNode1; Test("Test5", &pHead, nullptr, 0); DestroyList(pHead); } // 除了两个结点之外其他结点都成对出现 void Test6() { ListNode* pNode1 = CreateListNode(1); ListNode* pNode2 = CreateListNode(1); ListNode* pNode3 = CreateListNode(2); ListNode* pNode4 = CreateListNode(3); ListNode* pNode5 = CreateListNode(3); ListNode* pNode6 = CreateListNode(4); ListNode* pNode7 = CreateListNode(5); ListNode* pNode8 = CreateListNode(5); ConnectListNodes(pNode1, pNode2); ConnectListNodes(pNode2, pNode3); ConnectListNodes(pNode3, pNode4); ConnectListNodes(pNode4, pNode5); ConnectListNodes(pNode5, pNode6); ConnectListNodes(pNode6, pNode7); ConnectListNodes(pNode7, pNode8); ListNode* pHead = pNode1; int expectedValues[] = { 2, 4 }; Test("Test6", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int)); DestroyList(pHead); } // 链表中只有两个不重复的结点 void Test7() { ListNode* pNode1 = CreateListNode(1); ListNode* pNode2 = CreateListNode(2); ConnectListNodes(pNode1, pNode2); ListNode* pHead = pNode1; int expectedValues[] = { 1, 2 }; Test("Test7", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int)); DestroyList(pHead); } // 结点中只有一个结点 void Test8() { ListNode* pNode1 = CreateListNode(1); ConnectListNodes(pNode1, nullptr); ListNode* pHead = pNode1; int expectedValues[] = { 1 }; Test("Test8", &pHead, expectedValues, sizeof(expectedValues) / sizeof(int)); DestroyList(pHead); } // 结点中只有两个重复的结点 void Test9() { ListNode* pNode1 = CreateListNode(1); ListNode* pNode2 = CreateListNode(1); ConnectListNodes(pNode1, pNode2); ListNode* pHead = pNode1; Test("Test9", &pHead, nullptr, 0); DestroyList(pHead); } // 空链表 void Test10() { ListNode* pHead = nullptr; Test("Test10", &pHead, nullptr, 0); } int main(int argc, char* argv[]) { Test1(); Test2(); Test3(); Test4(); Test5(); Test6(); Test7(); Test8(); Test9(); Test10(); return 0; }
/* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } }; */ class Solution { public: ListNode* deleteDuplication(ListNode* pHead) { if (pHead == nullptr) return nullptr; ListNode* pPreNode = nullptr; ListNode* pNode = pHead; while (pNode != nullptr) { ListNode* pNext = pNode->next; bool needDelete = false; if (pNext != nullptr && pNode->val == pNext->val) needDelete = true; if (!needDelete) { pPreNode = pNode; pNode = pNode->next; } else { int value = pNode->val; ListNode* pToBeDel = pNode; while (pToBeDel != nullptr && pToBeDel->val == value) { pNext = pToBeDel->next; delete pToBeDel; pToBeDel = nullptr; pToBeDel = pNext; } if (pPreNode == nullptr) pHead = pNext; else pPreNode->next = pNext; pNode = pNext; } } return pHead; } };