算法题学习---删除有序链表中重复的元素-II

82 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天,点击查看活动详情

题目

描述

给出一个升序排序的链表,删除链表中的所有重复出现的元素,只保留原链表中只出现一次的元素。 例如: 给出的链表为1→2→3→3→4→4→5, 返回1→2→5. 给出的链表为1→1→1→2→3, 返回2→3.

数据范围:链表长度 0≤n≤10000,链表中的值满足∣val∣≤1000

要求:空间复杂度 O(n),时间复杂度 O(n)

进阶:空间复杂度 O(1),时间复杂度 O(n)

示例1

输入:
{1,2,2}
返回值:
{1}

示例2

输入:
{}
返回值:
{}

分析

分析特殊情况

由题目我们可以知道,当链表为空或者链表只有一个元素时,只需要返回链表头即可。

分析一般情况

首先由于我们不知道是否需要删除头结点,最好新建一个dummy节点指向头结点;

然后我们对链表进行遍历,检查前后两个元素是否相等:

  • 如果不等,则往后继续遍历;
  • 如果相等,那么我们需要进行内循环,向后找到所有相等的节点,并删除它们。

这里我们采用了三个节点pPrePre初始化为dummy节点,pPre初始化为head,pCur初始化为head->next,然后遍历对比pPre与pCur的值,如果不等,则更新上面三个指针,如果相等,则先删除pCur到最后一个相同值的节点,然后删除pPre,然后建立新的连接,并更新。

最后返回pReturn->next.

代码示例

注意,这里也涉及到我们在删除节点时的操作,需要使用一个临时变量缓存需要删除的节点,还有,我们最开始创建的dummy节点也不要忘记一并删除。

/**
 * struct ListNode {
 *  int val;
 *  struct ListNode *next;
 * };
 */

class Solution {
public:
    /**
     * 
     * @param head ListNode类 
     * @return ListNode类
     */
    ListNode* deleteDuplicates(ListNode* head) {
        // write code here
        if(nullptr == head || nullptr == head->next){
            return head;
        }

        ListNode *pReturn = new ListNode(-1);
        pReturn->next = head;
        ListNode *pPrePre = pReturn;
        ListNode *pPre = head;
        ListNode *pCur = head->next;

        while(nullptr != pCur){
            if(pPre->val != pCur->val){
                pPrePre = pPre;
                pPre = pCur;
                pCur = pCur->next;
            }else{
                //delete pCur same value
                while(nullptr != pCur && pPre->val == pCur->val){
                    ListNode* pTemp = pCur;
                    pCur = pCur->next;
                    delete pTemp;
                    pPre->next = pCur;
                }
                
                // delete pPre
                delete pPre;
                pPre = pCur;
                pPrePre->next = pPre;
                if(nullptr == pCur){
                    break;
                }else{
                    pCur = pCur->next;
                }
            }
        }
        ListNode *pTemp = pReturn;
        pReturn = pReturn->next;
        delete pTemp;

        return pReturn;
    }
};