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

题目描述

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

解题思路

需要两个指针,一个指向前一个节点pre,另一个指向当前节点p,如果遇到相等的节点,pre不动,p向后移动,直到遇到p和p.next不相等,pre就可以指向p.next。
注意:因为第一个节点可能重复了,那么会被删除,重复的节点需要全部删除,那么需要设置一个先前节点的指针。

非递归版

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* deleteDuplication(ListNode* pHead)
    {
        if(pHead==NULL || pHead->next==NULL)
            return pHead;
        //新建一个节点,防止头结点要被删除
        ListNode* newHead=new ListNode(-1);
        newHead->next=pHead;
        ListNode* pre=newHead;
        ListNode* p=pHead;
        ListNode* next=NULL;
        while(p!=NULL && p->next!=NULL){
            next=p->next;
            if(p->val==next->val)//如果当前节点的值和下一个节点的值相等
            {
                while(next!=NULL && next->val==p->val)//向后重复查找
                    next=next->next;
                pre->next=next;//指针赋值,就相当于删除
                p=next;
            }
            else//如果当前节点和下一个节点值不等,则向后移动一位
            {
                pre=p;
                p=p->next;
            }
        }
        return newHead->next;//返回头结点的下一个节点
    }
};

递归版

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) :
        val(x), next(NULL) {
    }
};
*/
class Solution {
public:
    ListNode* deleteDuplication(ListNode* pHead)
    {
        if(pHead==NULL || pHead->next==NULL)
            return pHead;      
        ListNode* current;        
        if(pHead->next->val==pHead->val){
            current=pHead->next->next;
            while (current != NULL && current->val==pHead->val)
                current=current->next;
            return deleteDuplication(current);                     
        }      
        else{
            current=pHead->next;
            pHead->next=deleteDuplication(current);
            return pHead;
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值