力扣第八十二题-删除排序链表中的重复元素 II

303 阅读3分钟

「这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战

前言

力扣第八十二题 删除排序链表中的重复元素 II 如下所示:

存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字。

返回同样按升序排列的结果链表。

示例 1:

输入: head = [1,2,3,3,4,4,5]
输出: [1,2,5]

示例 2:

输入: head = [1,1,1,2,3]
输出: [2,3]

一、思路

题目意思很简单就是删除链表中的重复项,且需要保留原始列表

因为题目中规定了需要保留原始链表,所以是不可以再新建一个链表来逐个添加不重复节点的。

找到链表中的重复项是一件比较容易的事情,找到重复项肯定是有一个指针 current 指向当前节点,另一个指针 next 指向下一个节点,只要这两个节点的值相等就说明重复了,然后一直 next 节点向下,直到出现不重复的值,如下图所示:

image.png

我们发现这个时候没办法让 current 的上一个节点的下一个元素指向 next

所以我们就需要一个前置节点 before 了,它始终指向 current 的上一个元素,详细步骤见下面的图解

图解算法(增加前置节点)

此处以实力中的 head = [1,2,3,3,4,4,5] 作为例子

  1. 我们先新增一个 before 节点,如下图所示:

1636461073(1).jpg

  1. 因为 currentnext 指向的元素 12 互不相等,故都指向自身的下一个元素

image.png

  1. 因为 currentnext 指向的元素 23 互不相等,故继续指向自身的下一个元素

image.png

  1. 此时 currentnext 指向的元素相等,此时 next 需一直向下找到与 current 不相等的元素,如下图所示:

image.png

  1. 删除重复元素

此时 before 节点的作用就体现出来了,我们只需将 before.next = nextcurrent = next , next = next.next 即可,如下图所示:

image.png

  1. 删除后续重复元素的步骤同上,就不过多赘述了。

二、实现

实现代码

在实现代码中为了简洁性,使用 before.next 代替了 current

    /**
     * 删除重复项
     * @param head
     * @return
     */
    public ListNode deleteDuplicates(ListNode head) {
        // 特殊情况
        if (head == null || head.next == null) {
            return head;
        }
        ListNode before = new ListNode(-1, head);   // 前置节点
        ListNode newHead = before;
        ListNode next = head.next;
        while (next != null) {
            if (next.val == newHead.next.val) {
                // 只要与当前值相等,就一直向下
                while (next != null && next.val == newHead.next.val) {
                    next = next.next;
                }
                // 删除该节点,和之前的节点
                newHead.next = next;
                if (next == null) { // 如果后面没有元素了
                    break;
                }
                next = next.next;
            } else {
                newHead = newHead.next;
                next = next.next;
            }
        }
        return before.next;
    }

测试代码

    public static void main(String[] args) {
        ListNode listNode1 = new ListNode(1, new ListNode(1, new ListNode(1, new ListNode(2, new ListNode(3)))));
        ListNode listNode2 = new ListNode(1, new ListNode(2, new ListNode(3, new ListNode(3, new ListNode(4, new ListNode(4, new ListNode(5)))))));
        ListNode listNode3 = new ListNode(1, new ListNode(1));
        new Number82().deleteDuplicates(listNode3);
    }

结果

image.png

三、总结

感谢看到最后,非常荣幸能够帮助到你~♥

如果你觉得我写的还不错的话,不妨给我点个赞吧!如有疑问,也可评论区见~