【leetcode】82. Remove Duplicates from Sorted List II

题目说明

https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/description/
给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字

解法1

该解法只使用一层循环,遍历链表,每次判断当前点与下一个结点的值是否相等,若相等,则删除下一个结点。但是这样与当前点所有相等的结点都删除后,无法判断当前是否需要删除,所以添加了一个标识位来判断是否需要删除当前点。
特别地当遍历链表结点后,还需要判断一个标识位,因为可能最后一个点因为无法满足遍历条件而不能被处理。
这种方法有些繁琐,推荐下面两种方法。

/*
 * 时间复杂度:O(n)
 * 遍历链表,若cur的下一个结点与cur的值相等,则删除下一结点,并标记cur为待删除结点(delflag = 1)
 * 直到不再有相等的,再将cur删除,并将delflag置0
 */
ListNode* deleteDuplicates(ListNode* head) {
    ListNode *dummy = new ListNode(0);
    dummy->next = head;

    ListNode *pre = dummy;
    ListNode *cur = NULL;
    ListNode *next = NULL;
    int delflag = 0;

    while(pre->next && pre->next->next){
        cur = pre->next;
        next = pre->next->next;

        if (cur->val == next->val){
            cur->next = next->next;
            delflag = 1;
            delete next;
        } else{
            if (delflag == 1){
                delflag = 0;
                pre->next = cur->next;
                delete cur;
                continue;
            }
            pre = pre->next;
        }
    }
    if (delflag == 1){
        pre->next = cur->next;
        delete cur;
    }
    return dummy->next;
}

解法2

当判断到有相等结点时,开启循环找到所有相等的点,遇到相等的点,则删除相等的前一个点,遍历指针后移。这样遍历过程只保留最后一个相等的结点。最后再将该结点删除即可。

/*
 * 时间复杂度:O(n)
 * 与上一种解法不同的是,遇到相等的点,删除相等前一个点,遍历指针后移
 * 遇到了相等的点,开始遍历找到所有相等的点也是需要借鉴的
 */
ListNode* deleteDuplicates(ListNode* head) {
    ListNode *dummy = new ListNode(0);
    dummy->next = head;

    ListNode *pre = dummy;
    ListNode *cur = NULL;
    ListNode *del = NULL;

    while(pre->next){
        cur  = pre->next;

        if (cur->next && cur->val == cur->next->val){
            int x = cur->val;

            while (cur->next && cur->next->val == x){
                del = cur;
                cur = cur->next;
                delete del;
            }

            pre->next = cur->next;
            delete cur;
        } else
            pre = pre->next;
    }

    return dummy->next;
}

解法3

借鉴第二种解法2,改造第一种解法。

/*
 * 时间复杂度:O(n)
 * 根据第二种解法改造第一种解法
 * 遇到了相等的结点,则进行循环遍历,找到所有相等的点
 * 与第二种解法不同的是 这里是删除新找到的结点
 */
ListNode* deleteDuplicates(ListNode* head) {
    ListNode *dummy = new ListNode(0);
    dummy->next = head;

    ListNode *pre = dummy;
    ListNode *cur = NULL;
    ListNode *del = NULL;

    while(pre->next) {
        cur = pre->next;

        if (cur->next && cur->next->val == cur->val) {
            int x = cur->val;

            while (cur->next && cur->next->val == x) {
                del = cur->next;
                cur->next = cur->next->next;
                delete del;
            }

            pre->next = cur->next;
            delete cur;
        } else
            pre = pre->next;
    }

    return dummy->next;
}
posted @ 2018-09-02 11:21  JESSET  阅读(124)  评论(0编辑  收藏  举报