Leetcode ☞ 82. Remove Duplicates from Sorted List II ☆

本文介绍了一种高效算法,用于从已排序的链表中移除所有重复出现的元素,只保留唯一的数值。提供了三种不同的实现方式,并附带了剑指Offer 57题的两种解题思路。

82. Remove Duplicates from Sorted List II

My Submissions
Total Accepted: 67074  Total Submissions: 253195  Difficulty: Medium

Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.

For example,
Given 1->2->3->3->4->4->5, return 1->2->5.
Given 1->1->1->2->3, return 2->3.











我的AC:(4ms,最快一批)

struct ListNode* deleteDuplicates(struct ListNode* head) {
    if(!head || !head->next)
        return head;
    struct ListNode *dummy = (struct ListNode*)malloc(sizeof(struct ListNode));
    dummy->next = head;
    struct ListNode *p = dummy;
    struct ListNode *last = NULL;
    
    while(p->next && p->next->next){//p->next->next必须要加,不然runtime error
        if(p->next->val == p->next->next->val){
            last = p->next;
            p->next = p->next->next;
        }
        else if(last && p->next->val == last->val)
            p->next = p->next->next;
        else
            p = p->next;
    }
    if(last && p->next->val == last->val)
            p->next = p->next->next;
            
    return dummy->next;
}

关键:

循环后还要再加一个if判断。

if(last && p->next->val == last->val)
        p->next = p->next->next;
如果不加则【1,1,1,1,1】和【1,1,1,1】输出为【1】

但这是用了testcase才知道的,自己想不到。


另一种写法:

struct ListNode* deleteDuplicates(struct ListNode* head) {
    if(!head || !head->next)
        return head;
    struct ListNode *dummy = (struct ListNode*)malloc(sizeof(struct ListNode));
    dummy->next = head;
    struct ListNode *p = dummy;
    struct ListNode *curr = head;
    
    while(curr){
        if(curr->next && curr->val == curr->next->val){
            while(curr->next && curr->val == curr->next->val)
                curr = curr->next;
        }
        else{
            p->next = curr;
            p = p->next;
        }
        curr = curr->next;
    }
    p->next=NULL;
    return dummy->next;
}

更简洁的写法:

struct ListNode* deleteDuplicates(struct ListNode* head) {
    if(!head || !head->next)
        return head; 
    struct ListNode *dummy = (struct ListNode*)malloc(sizeof(struct ListNode)); 
    dummy->next = head;
    struct ListNode *pre = dummy, *cur = head;
    int preVal = head->val-1; //记录下当前节点的值以便下次循环对比使用,初始值应该对头节点产生影响,所以设成与头节点值有区别。
    while(cur){
        if(cur->val != preVal && ( !cur->next || cur->next->val != cur->val)) {//only when both the previous value and the next are not equal to the current one - by the way, the next node is null will definitely considered unequal, we can then collect it;
            pre->next = cur;
            pre = pre->next;
        }
        preVal = cur->val;
        cur = cur->next;
    }
    pre->next = NULL; //terminate the list;
    return dummy->next;
}


剑指offer57题:

一.返回类型为void

void DeleteNode(ListNode** pListHead, ListNode* pToBeDeleted)
{
    if(!pListHead || !pToBeDeleted)
        return;

    // 要删除的结点不是尾结点
    if(pToBeDeleted->m_pNext != NULL)
    {
        ListNode* pNext = pToBeDeleted->m_pNext;
        pToBeDeleted->m_nValue = pNext->m_nValue;
        pToBeDeleted->m_pNext = pNext->m_pNext;
 
        delete pNext;
        pNext = NULL;
    }
    // 链表只有一个结点,删除头结点(也是尾结点)
    else if(*pListHead == pToBeDeleted)
    {
        delete pToBeDeleted;
        pToBeDeleted = NULL;
        *pListHead = NULL;
    }
    // 链表中有多个结点,删除尾结点
    else
    {
        ListNode* pNode = *pListHead;
        while(pNode->m_pNext != pToBeDeleted)
        {
            pNode = pNode->m_pNext;            
        }
 
        pNode->m_pNext = NULL;
        delete pToBeDeleted;
        pToBeDeleted = NULL;
    }
}


二、返回类型是ListNode*

    ListNode* deleteDuplication(ListNode* pHead)
    {
        if (pHead == NULL) return NULL;
        
        ListNode *curr = pHead;
        ListNode *prev = NULL;
        ListNode *pNext;
        ListNode *newHead = pHead;
        
        while(curr){
            pNext = curr->next;
            int value = curr->val;
        	bool shouldDel = false;
            if(pNext != NULL && pNext->val == value)
                shouldDel = true;
            
            if(shouldDel){//要删除
                ListNode *pToBeDel = curr;
                while(pToBeDel != NULL && pToBeDel->val == value){
                    pNext = pToBeDel->next;
                    delete pToBeDel;
                    pToBeDel = NULL;
                    pToBeDel = pNext;
                }
                if(prev == NULL)//头结点改变
                    newHead = pNext;
                else
                    prev->next = pNext;
                
                curr = pNext;
            }
            else{//不要删除
                prev = curr;
                curr = curr->next;
            }   
        }
        return newHead;
    }








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值