【数据结构】链表相关练习题:删除链表中重复的节点

  • 题目描述

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

  • 思路分析

我们可以给定两个一前一后的指针n1,n2,当两个指针的val不一样时,不需要处理,直到一样时,n1不动,让第二个指针n2往后走,走到跟n2不相同的地方,把n1和n2之间的数字删掉,再想办法把n1和n2链接起来,只要遇到相同的,就又重复前面的逻辑,这里还有一个问题要注意,就是删除时,得有它的前一个指针,所以还得有一个指针永远记录n1的前一个。

(补充一个简单的链表的去重:如果是有n个3,但是要保留一个时,当两个指针一样时,删掉一个,然后前面的指针继续指向下一个,一直这样,两个指针相同时,删掉一个,直到链表结束)

注意:如果链表只有一个节点或者没有节点的时候,要单独处理,这里有一个原则,就是一般情况下,如果你写的代码能正常处理一个节点都没有的情况就不用判断,如果不行,就要判断;还有一个就是,如果你一开始就要动两个或两个指针以上的指针,就要单独处理一下,剩下的不用处理

具体实现代码如下:

/*
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;
        struct ListNode* prev=NULL;
        struct ListNode* n1=pHead;
        struct ListNode* n2=n1->next;
        while(n2!=NULL)
        {
            if(n1->val!=n2->val)
            {
                prev=n1;
                n1=n2;
                n2=n2->next;
            }
            else
            {
               while(n2&&n1->val==n2->val) 
               {
                   n2=n2->next;
               }
                if(prev!=NULL)
                {
                    prev->next=n2;
                }
                else
                {
                    pHead=n2;
                }
                //删除掉重复的节点
                while(n1!=n2)
                {
                    struct ListNode* next=n1->next;
                    free(n1);
                    n1=next;
                }
                n1=n2;
                if(n2)
                    n2=n2->next;
            }
        }
        return pHead;
    }
};

oj链接:https://www.nowcoder.com/practice/fc533c45b73a41b0b44ccba763f866ef?tpId

猜你喜欢

转载自blog.csdn.net/qq_42270373/article/details/83034282