链表二:删除排序链表中的重复元素

前言

单链表由于其结构不是很完美,造成了面试官比较喜欢在单链表上出题。

删除排序链表中的重复元素Ⅰ

存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除所有重复的元素,使每个元素 只出现一次 。
返回同样按升序排列的结果链表。
在这里插入图片描述
输入:head = [1,1,2]
输出:[1,2]

看到题目我们不要慌忙去写代码,先去画画图把你所想的过程自己一步步推算下去,看看是否能行。
在这里插入图片描述
在这里插入图片描述
完整代码如下:

struct ListNode* deleteDuplicates(struct ListNode* head)
{
    //当头指针为NULL,不需要排序
    //或者head->next==NULL时,链表中只有一个结点,不需要进行排序
    if(head==NULL||head->next==NULL)
    {
        return head;
    }
    struct ListNode*cur=head;
    struct ListNode*next=head->next;
    while(next!=NULL)
    {
        if(cur->val==next->val)
        {
            struct ListNode*ToDelete=next;
            cur->next=next->next;
            next=next->next;
            free(ToDelete);
            ToDelete=NULL;
        }
        else
        {
            cur=next;
            next=next->next;
        }
    }
    return head;
}

删除排序链表中的重复元素Ⅱ

我们在第一题的基础上我们升级难度,题目如下:

存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中没有重复出现 的数字。
返回同样按升序排列的结果链表。
在这里插入图片描述
输入:head = [1,2,3,3,4,4,5]
输出:[1,2,5]

还是照着上题的思路,先判断有什么特殊情况
在这里插入图片描述
在这里插入图片描述
当next为NULL时,循环结束。
完整代码如下:

struct ListNode* deleteDuplicates(struct ListNode* head)
{
    //特殊情况:当传进来的链表为空或者只有一个节点,就表明不可能会有重复的节点
    if (head == NULL || head->next == NULL)
    {
        return head;
    }
    //创建一个哨兵位的头结点,并把它与传进来的链表进行链接,以方便插入
    struct ListNode* temphead = (struct ListNode*)malloc(sizeof(struct ListNode));
    temphead->next = head;

    struct ListNode* prev = temphead;
    struct ListNode* cur = head;
    struct ListNode* next = cur->next;
    while (next != NULL)
    {
        if (cur->val == next->val)
        {
            //如果相等,则判断next之后的节点是否也是该数,是就继续走,不是则跳出循环
            while (next != NULL)
            {
                next = next->next;
                if (next != NULL && next->val != cur->val)
                {
                    break;
                }
            }
            //从cur到next这个前闭后开的区间内,这些节点的val都是重复出现的数,要把它删除
            while (next != NULL && cur->val != next->val)
            {
                struct ListNode* del = cur;
                cur = cur->next;
                free(del);
            }
            //到了这里next一定是与cur->val不相等了,把prev->next链接上
            prev->next = next;
        }
        else
        {

            prev->next = cur;
            prev = prev->next;
            cur = next;
        }
        //如果next==NULL了,则不需要往下遍历了,不然会有空指针的问题
        if (next != NULL)
        {
            next = next->next;
        }
    }

    head = temphead->next;
    free(temphead);
    temphead=NULL;
    return head;
}

感谢各位大佬拜读文章。

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值