LeetCode 82. 删除排序链表中的重复元素 II

截止到目前我已经写了 600多道算法题,其中部分已经整理成了pdf文档,目前总共有1000多页(并且还会不断的增加),大家可以免费下载
下载链接https://pan.baidu.com/s/1hjwK0ZeRxYGB8lIkbKuQgQ
提取码:6666

在这里插入图片描述
在这里插入图片描述
前面我们刚讲过595,删除排序链表中的重复元素,这题和595题不同的是,如果有数字相同的节点,那么这些数字相同的节点要全部删除。


这题的解决思路就是使用两个指针,一个指针cur指向当前节点,一个指针pre指向当前节点cur的前一个节点。cur始终和他的下一个节点比较,如果相同就往后移,如果不相同我们就需要判断pre的下一个节点是否是cur,如果是cur说明没有相同的节点,如果不是cur说明有相同的节点,我们就要删除,叙述不太好理解,我做个视频来看一下
视频链接
在这里插入图片描述
最后在来看下代码

public ListNode deleteDuplicates(ListNode head) {
    if (head == null || head.next == null)
        return head;
    //添加一个dummy节点
    ListNode dummy = new ListNode(0);
    //让dummy节点的next指针指向head。
    dummy.next = head;
    //指向当前遍历的节点
    ListNode cur = head;
    //指向当前节点pre的前一个节点
    ListNode pre = dummy;
    while (cur != null) {
        while (cur.next != null && cur.val == cur.next.val) {
            //如果有重复的,cur就一直往下走
            cur = cur.next;
        }
        //判断上面有没有重复的节点,如果pre.next == cur,说明没有
        //重复的节点。否则说明有重复的节点,然后还要把重复的节点给删除
        if (pre.next == cur) {
            pre = pre.next;
        } else {
            //有重复的就删除
            pre.next = cur.next;
        }
        cur = cur.next;
    }
    return dummy.next;
}

递归方式解决

除了上面的方式以外,我们还可以使用递归的方式来解决,我们先定义一个函数deleteDuplicates(ListNode head)表示删除重复的节点。


如果head.val != head.next.val,也就是说当前节点和他的下一个节点值不一样,我们不做任何的删除,直接递归head节点的下一个节点,也就是

head.next = deleteDuplicates(head.next);

如果head.val == head.next.val,说明有重复的节点,这里到底是重复一个还是重复多个,我们不知道,需要通过一个循环来确定。然后把重复的全部删除,也就是

while (head.next != null && head.val == head.next.val)
    head = head.next;
return deleteDuplicates(head.next);

那递归的终止条件是什么呢,就是节点为空,或者只有一个节点,这种情况下是不可能有重复的,直接返回即可。我们来看下完整代码

public ListNode deleteDuplicates(ListNode head) {
    if (head == null || head.next == null)
        return head;
    if (head.val != head.next.val) {
        //如果当前节点和下一个节点的值不相同
        head.next = deleteDuplicates(head.next);
        return head;
    } else {
        //如果当前节点和下一个节点的值相同,说明出现了重复的,
        //把重复的全部给删除
        while (head.next != null && head.val == head.next.val)
            head = head.next;
        return deleteDuplicates(head.next);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据结构和算法

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值