【剑指offer】8.删除链表中重复的结点
总目录:
1.问题描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表 1->2->3->3->4->4->5 处理后为 1->2->5
数据范围:链表长度满足 0≤n≤1000 ,链表中的值满足 1≤val≤1000
进阶:空间复杂度 O(n) ,时间复杂度 O(n)
例如输入{1,2,3,3,4,4,5}时,对应的输出为{1,2,5},对应的输入输出链表如下图所示:
2.问题分析
关键是有序,则相同元素挨在一起
可采取的方法:
1暴力迭代
- step 1:给链表前加上表头,方便可能的话删除第一个节点。
- step 2:遍历链表,每次比较相邻两个节点,如果遇到了两个相邻节点相同,则新开内循环将这一段所有的相同都遍历过去。
- step 3:在step 2中这一连串相同的节点前的节点直接连上后续第一个不相同值的节点。
- step 4:返回时去掉添加的表头
2哈希表法,可用于快速查表
- step 1:遍历一次链表用哈希表(key-value)记录每个节点值出现的次数。
- step 2:在链表前加一个节点值为0的表头,方便可能的话删除表头元素。
- step 3:再次遍历该链表,对于每个节点值检查哈希表中的计数,只留下计数为1的,其他情况都删除。
- step 4:返回时去掉增加的表头。
3.代码实例
迭代法
1 /* 2 struct ListNode { 3 int val; 4 struct ListNode *next; 5 ListNode(int x) : 6 val(x), next(NULL) { 7 } 8 }; 9 */ 10 class Solution { 11 public: 12 ListNode* deleteDuplication(ListNode* pHead) { 13 //加表头 14 ListNode* newHead = new ListNode(1); 15 newHead->next = pHead; 16 ListNode* pCur = newHead; 17 18 //遍历比较接下来相邻的两个值 19 int curSameNUm = 0; 20 while (pCur->next != NULL && pCur->next->next != NULL) { 21 //遇到两个节点的值不同 22 if (pCur->next->val != pCur->next->next->val) { 23 pCur = pCur->next; 24 continue; 25 } 26 27 //跳过这段相同值 28 curSameNUm = pCur->next->val; 29 while (pCur->next != NULL && pCur->next->val == curSameNUm) { 30 pCur->next = pCur->next->next; 31 } 32 } 33 34 pHead = newHead->next; 35 delete newHead; 36 return pHead; 37 } 38 };
哈希表记录重复次数
1 /* 2 struct ListNode { 3 int val; 4 struct ListNode *next; 5 ListNode(int x) : 6 val(x), next(NULL) { 7 } 8 }; 9 */ 10 class Solution { 11 public: 12 ListNode* deleteDuplication(ListNode* pHead) { 13 //空链表 14 if (pHead == NULL) 15 return NULL; 16 17 //记录每个节点值出现过的次数 18 unordered_map<int, int> mp; 19 ListNode* pCur = pHead; 20 while (pCur != NULL) { 21 mp[pCur->val]++; 22 pCur = pCur->next; 23 } 24 25 //加表头 26 ListNode* newHead = new ListNode(1); 27 newHead->next = pHead; 28 pCur = newHead; 29 while (pCur != NULL && pCur->next != NULL) { 30 if (mp[pCur->next->val] > 1) { 31 pCur->next = pCur->next->next; 32 } 33 else{ 34 pCur=pCur->next; 35 } 36 } 37 38 pHead = newHead->next; 39 delete newHead; 40 return pHead; 41 } 42 };