题目链接

牛客网
LeetCode

题目描述

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

18.2 删除链表中重复的结点II - 图1

解题思路

方法一:使用set,暴力解法

根据题意,显然如果能够知道重复的值是什么,然后再遍历一次单链表,删除重复值即可。
找重复值的具体步骤:
1.初始化:set st
2. 遍历单链表相邻两个元素,如果相等,就加入到set当中
3. 直到单链表遍历完

删除重复值的具体步骤:
1.初始化:pre指针指向重复值的前一个节点,cur指向当前遍历的节点值
2.遍历单链表当前元素,然后再set中检查,如果是重复值,就删除,pre->next = cur->next
3. 否则,不是重复值,pre = pre->next, cur = cur->next
4. 知道单链表遍历完

  1. class Solution {
  2. public:
  3. ListNode* deleteDuplication(ListNode* pHead)
  4. {
  5. if (!pHead) return pHead;
  6. set<int> st;
  7. ListNode *pre = pHead;
  8. ListNode *cur = pHead->next;
  9. while (cur) {
  10. if (pre->val == cur->val) {
  11. st.insert(pre->val);
  12. }
  13. pre = pre->next;
  14. cur = cur->next;
  15. }
  16. ListNode *vhead = new ListNode(-1);
  17. vhead->next = pHead;
  18. pre = vhead;
  19. cur = pHead;
  20. while (cur) {
  21. if (st.count(cur->val)) {
  22. cur = cur->next;
  23. pre->next = cur;
  24. }
  25. else {
  26. pre = pre->next;
  27. cur = cur->next;
  28. }
  29. }
  30. return vhead->next;
  31. }
  32. };
  • 时间复杂度:O(2n),遍历了2次单链表
  • 空间复杂度:最坏O(n), 最好O(1)

方法二:直接删除法

根据方法一,可以优化,在遍历单链表的时候,检查当前节点与下一点是否为相同值,如果相同,继续查找祥同值的最大长度,然后指针改变指向。

  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||!pHead->next)
  15. return pHead;
  16. ListNode *vhead = new ListNode(-1);
  17. vhead->next = pHead;
  18. ListNode *pre = vhead,*cur = pHead;
  19. while(cur){
  20. if(cur->next&&(cur->val==cur->next->val)){
  21. int tmp = cur->val;
  22. while(cur&&cur->val==tmp){
  23. cur = cur->next;
  24. }
  25. pre->next = cur;
  26. }else{
  27. pre = cur;
  28. cur = cur->next;
  29. }
  30. }
  31. return vhead->next;
  32. }
  33. };
  34. /*
  35. struct ListNode {
  36. int val;
  37. struct ListNode *next;
  38. ListNode(int x) :
  39. val(x), next(NULL) {
  40. }
  41. };
  42. */
  43. class Solution {
  44. public:
  45. ListNode* deleteDuplication(ListNode* pHead) {
  46. ListNode* hair = new ListNode(0);
  47. hair->next = pHead;
  48. ListNode* pre = hair;
  49. ListNode* cur = pHead;
  50. while(cur){
  51. if(cur->next&&cur->val==cur->next->val){
  52. cur = del(cur);
  53. pre->next = cur;
  54. }else{
  55. pre = cur;
  56. cur = cur->next;
  57. }
  58. }
  59. return hair->next;
  60. }
  61. ListNode* del(ListNode* node){
  62. int val = node->val;
  63. while(node&&node->val==val){
  64. node = node->next;
  65. }
  66. return node;
  67. }
  68. };
  1. /**
  2. * Definition for singly-linked list.
  3. * public class ListNode {
  4. * int val;
  5. * ListNode next;
  6. * ListNode() {}
  7. * ListNode(int val) { this.val = val; }
  8. * ListNode(int val, ListNode next) { this.val = val; this.next = next; }
  9. * }
  10. */
  11. class Solution {
  12. public ListNode deleteDuplicates(ListNode head) {
  13. ListNode hair = new ListNode();
  14. hair.next = head;
  15. ListNode pre = hair, cur = head;
  16. while(cur!=null){
  17. int val = cur.val;
  18. boolean flag = true;
  19. while(cur.next != null && cur.next.val == val){
  20. cur = cur.next;
  21. flag = false;
  22. }
  23. if(flag){
  24. pre = pre.next;
  25. }else{
  26. pre.next = cur.next;
  27. }
  28. cur = cur.next;
  29. }
  30. return hair.next;
  31. }
  32. }

保留重复节点中第一个节点

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode hair = new ListNode();
        hair.next = head;
        ListNode pre = head;
        ListNode cur = head;
        while(cur!=null){
            int val = cur.val;
            while(cur!=null && cur.val == val){
                cur = cur.next;
            }
            pre.next = cur;
            pre = cur;
        }
        return hair.next;
    }
}
  • 时间复杂度:O(n)
  • 空间复杂度:O(1)