Leetcode 82. 删除排序链表中的重复元素 II

Posted Uitachi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Leetcode 82. 删除排序链表中的重复元素 II相关的知识,希望对你有一定的参考价值。

问题描述

给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。

示例 1:

输入: 1->2->3->3->4->4->5
输出: 1->2->5
示例 2:

输入: 1->1->1->2->3
输出: 2->3

代码

法一、采用找重复之前和找重复之后,时间复杂度 O(n2) ----自己所写

 1 class Solution {
 2 public:
 3     ListNode* searchPreDuplicates(ListNode *head, ListNode *p){
 4         ListNode* q = head;
 5         while(q != NULL&& q->next != NULL){
 6             if(q->next == p)
 7                 break;
 8             q = q->next;
 9         }
10         return q;
11     }
12     ListNode* deleteDuplicates(ListNode* head) {
13         ListNode* preHead= new ListNode(-1);
14         ListNode *p = preHead;
15         p->next = head;
16         p = p->next;
17         //ListNode* p = head;
18         while(p != NULL && p->next != NULL){
19             if(p->val != p->next->val){
20                 p = p->next;
21             }
22             else{
23                 ListNode* pre = searchPreDuplicates(preHead,p);
24                 
25                 while(p != NULL && p->next != NULL && p->val == p->next->val)  p = p->next;  
26                 //找重复数字的下一个节点
27                 
28                 ListNode* post = p->next;
29                 
30 
31                 pre->next = post;
32                 p = post;
33 
34             }
35         }
36         return preHead->next;
37     }
38 };

法二、采用快慢指针,时间复杂度O(n)-----学习他人

 1 class Solution {
 2 public:
 3  
 4     ListNode* deleteDuplicates(ListNode* head) {
 5         //创建哑节点
 6         ListNode *preHead = new ListNode(-1);
 7         preHead->next = head;
 8         //创建快慢指针 
 9         ListNode *slow = preHead;  //慢指针用于指向重复数字的前一个数字
10         ListNode *fast = head;   //快指针用于寻找重复数字
11 
12         while(fast != NULL && fast->next != NULL){
13             if(fast->val != fast->next->val){   //分情况讨论,如1->2和1->1->2
14                 if(slow->next == fast ) //此时之前没有重复数字
15                     slow = fast;
16                 else{
17                     slow->next = fast->next;   //此时将略过重复数字
18                 }
19             } 
20             fast = fast->next;
21         }
22         
23         if(slow->next != fast) slow->next = fast->next;
24         
25         return preHead->next;
26         
27     }
28 };

此方法不能忽略最后的[1,1]情况判断,即上面第23行很关键。因为快慢指针是前后挨着。若输入的数据全部是重复数字,那么相当于fast指针一直前进,没有执行更新slow指针的值(第17行)

就跳出循环,所以最后再更新slow指针的值。

总结

1.本题重复数字在开头的处理方法为 : 哑节点

2.学习了对于链表设置快慢指针的方法,此方法的实质依旧是未重复数字之前的数字指向重复完成数字之后,只不过实现时用到了双指针

class Solution {
public:
    ListNode* searchPreDuplicates(ListNode *head, ListNode *p){
        ListNode* q = head;
        while(q != NULL&& q->next != NULL){
            if(q->next == p)
                break;
            q = q->next;
        }
        return q;
    }
    ListNode* deleteDuplicates(ListNode* head) {
        ListNode* preHead= new ListNode(-1);
        ListNode *p = preHead;
        p->next = head;
        p = p->next;
        //ListNode* p = head;
        while(p != NULL && p->next != NULL){
            if(p->val != p->next->val){
                p = p->next;
            }
            else{
                ListNode* pre = searchPreDuplicates(preHead,p);
                
                while(p != NULL && p->next != NULL && p->val == p->next->val)  p = p->next;  
                //找重复数字的下一个节点
                
                ListNode* post = p->next;
                

                pre->next = post;
                p = post;

            }
        }
        return preHead->next;
    }
};

以上是关于Leetcode 82. 删除排序链表中的重复元素 II的主要内容,如果未能解决你的问题,请参考以下文章

leetcode(82)---删除排序链表中的重复元素(双指针)

LeetCode 82. 删除排序链表中的重复元素 II

LeetCode 82. 删除排序链表中的重复元素 II

LeetCode82----删除排序链表中的重复元素 II

「LeetCode」82. 删除排序链表中的重复元素 II

「LeetCode」82. 删除排序链表中的重复元素 II