剑指offer----删除链表中的重复结点

本文介绍了一种算法,用于删除排序链表中的重复结点,通过使用两个指针prePtr和curPtr,以及两个标记flag和flag2来处理特殊情况,确保链表头结点也能被正确处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
//用两个指针,prePtr和curPtr,需要注意的是,有可能第一个结点和第二个结点的值
//一样,此时由于ListNode* curPtr=pHead->next,*prePtr=pHead;会造成第一个结点没
//删除掉,所以需要标记一下,用flag2,如果第一个结点和第二个结点相等,则flag2
//置为true
class Solution {
public:
    ListNode* deleteDuplication(ListNode* pHead)
    {
    //为空和一个结点直接返回
        if(pHead==NULL)return NULL;
        if(pHead->next==NULL)return pHead;
        
        //flag用来标记preValue的值是否有效,flag2用来标记是否需要删除第一个结点
        bool flag=false,flag2=false;
        int preValue=0;
        ListNode* curPtr=pHead->next,*prePtr=pHead;
        //判断第一个结点和第二个结点是否相等
        if(pHead->val==pHead->next->val)
        {
            flag=true;
            flag2=true;
            preValue=pHead->val;
        }
        //分两种情况,preValue值有效时,和preValue值无效时
        while(curPtr!=NULL)
        {
            if(flag==false)
            {
                if(curPtr->next==NULL)break;
                else
                {
                    if(curPtr->val==curPtr->next->val)
                    {
                        prePtr->next=curPtr->next->next;
                        preValue=curPtr->val;
                        delete curPtr->next;
                        delete curPtr;
                        curPtr=prePtr->next;
                        flag=true;
                    }
                    else
                    {
                        curPtr=curPtr->next;
                        prePtr=prePtr->next;
                    }
                }
            }
            else
            {
                if(preValue==curPtr->val)
                {
                    prePtr->next=curPtr->next;
                    delete curPtr;
                    curPtr=prePtr->next;
                }
                else
                {
                    flag=false;
                }
            }
        }
        if(flag2==false)return pHead;
        else
        {
            auto p=pHead->next;
            delete pHead;
            return p;
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值