虚拟头节点秒杀链表问题
在做链表相关题的时候,常常需要针对头节点单独考虑,但实际上对头节点进行处理的代码逻辑与非头节点的又特别地相似,此时通过在链表头节点前增加虚拟头节点,可以既使得代码更加优美又能避免对头节点得单独考虑。
82. 删除排序链表中的重复元素 II
题意:删除排序链表中所有含有重复数字的节点,只保留原始链表中没有出现的数字。
解题思路
以链表 1->1->1->2->3 为栗子,删除值为 1 的节点。
删除前:
删除后
在原链表的头节点前增加虚拟头节点:
定义两个指针 pre/cur,分别指向虚拟头节点和头节点
当 cur 指向的节点的值等于其下一个节点的值时,右移 cur 直到其指向的节点的值与其下一个节点的值不等
此时,将 pre 指向的节点指向 cur 指向的节点的下一个节点,即 pre->next = cur->next,相当于删除链表中所有节点值为 1 的节点
继续右移 cur,判断是否还有其指向的节点的值与其下一个节点值相等,同时右移 pre,直至 cur 指向链表尾节点
Show me the Code
1 // c++ 2 ListNode* deleteDuplicates(ListNode* head) { 3 /* 创建虚拟头节点 */ 4 ListNode* dummyHead = new ListNode(0); 5 dummyHead->next = head; 6 7 ListNode* pre = dummyHead; 8 while (pre->next != nullptr) { 9 ListNode *cur = pre->next; 10 /* 当前节点的值等于其下一节点的值,右移当前节点到其下一节点 */ 11 while (cur->next != nullptr && cur->val == cur->next->val) { 12 cur = cur->next; 13 } 14 15 /* 当前节点不是 pre 节点的下一节点,则将 pre 节点的下一节点指向当前 16 节点的下一节点,相当于删除当前所有含跟当前节点值相等的节点 */ 17 if (cur != pre->next) { 18 pre->next = cur->next; 19 /* 否则,pre 节点右移 */ 20 } else { 21 pre = pre->next; 22 } 23 } 24 25 /* 释放虚拟头节点空间,防止内存泄漏 */ 26 ListNode* retNode = dummyHead->next; 27 delete dummyHead; 28 return retNode; 29 }
更多精彩
关注公众号 『 TanLiuYi00 』,回复【算法】或【python】即可获取高清无码的经典算法或 python 电子书~
公众号:【程序员小熊】华为程序员,公众号主要分享:各大厂笔试/面试中的高频算法题、编程语言和后台开发相关资料等。