「力扣」第 82 题:删除排序链表中的重复元素 II(中等)


「力扣」第 82 题:删除排序链表中的重复元素 II(中等)

链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii;

传送门:82. 删除排序链表中的重复元素 II

给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。

示例 1:

输入: 1->2->3->3->4->4->5
输出: 1->2->5

示例 2:

输入: 1->1->1->2->3
输出: 2->3

方法一:穿针引线

Java 代码:

class ListNode {
    int val;
    ListNode next;

    ListNode(int x) {
        val = x;
    }

    public ListNode(int[] nums) {
        if (nums == null || nums.length == 0) {
            throw new IllegalArgumentException("arr can not be empty");
        }
        this.val = nums[0];
        ListNode curr = this;
        for (int i = 1; i < nums.length; i++) {
            curr.next = new ListNode(nums[i]);
            curr = curr.next;
        }
    }

    @Override
    public String toString() {
        StringBuilder s = new StringBuilder();
        ListNode cur = this;
        while (cur != null) {
            s.append(cur.val);
            s.append(" -> ");
            cur = cur.next;
        }
        s.append("NULL");
        return s.toString();
    }
}

public class Solution {

    public ListNode deleteDuplicates(ListNode head) {
        if (head == null) {
            return null;
        }
        // 只要涉及头结点的操作,设置虚拟头结点避免对链表第 1 个结点的分类讨论
        ListNode dummyNode = new ListNode(-1);
        dummyNode.next = head;
        ListNode curNode = dummyNode;
        while (curNode.next != null && curNode.next.next != null) {
            // 如果接连两个结点的 val 相等,至少要把它们都删掉
            if (curNode.next.val == curNode.next.next.val) {
                // 要删除的起点至少应该是当前判断相同的结点的第 2 个
                ListNode delNode = curNode.next.next;
                // 如果后面还有相同的结点,delNode 后移一位,即 delNode 应该是指向相同的结点的最后一个
                while (delNode.next != null && delNode.next.val == delNode.val) {
                    delNode = delNode.next;
                }
                curNode.next = delNode.next;
                delNode.next = null;
            } else {
                curNode = curNode.next;
            }
        }
        return dummyNode.next;
    }
}

关键:要两个两个一起判断。

Java 代码:

public class Solution2 {

    public ListNode deleteDuplicates(ListNode head) {
        if (head == null) {
            return null;
        }

        // 这里我们要清楚,例如 1 1 2 3 ,头结点也是有可能被删除的,所以要设置虚拟头结点
        // 只要涉及头结点的操作,我们都设立虚拟头结点
        ListNode dummyNode = new ListNode(-1);
        dummyNode.next = head;

        ListNode curNode = dummyNode;
        // 题目要求的删除结点这个操作是站在被删除结点前面的
        // 所以循环可以继续的条件应该这样写
        while (curNode.next != null && curNode.next.next != null) {
            // 如果接连两个结点的 val 相等,至少要把它们都删掉
            if (curNode.next.val == curNode.next.next.val) {
                // 要删除的起点至少应该是当前判断相同的结点的第 2 个
                ListNode delNode = curNode.next.next;
                // 如果后面还有相同的结点,delNode 后移一位,即 delNode 应该是指向相同的结点的最后一个
                // 注意:这里得用循环,例如: 1 2 2 2 2 2 2 2 2 3 3 3
                // 得让 delNode 结点挪到最后一个 2 上
                while (delNode.next != null && delNode.next.val == delNode.val) {
                    delNode = delNode.next;
                }

                // 接下来把有重复的链表段删除就可以了
                // 1        2   2   2         3
                // curNode          delNode
                curNode.next = delNode.next;
                delNode.next = null;
            } else {
                // 否则向前走一步
                curNode = curNode.next;
            }
        }
        return dummyNode.next;
    }

    public static void main(String[] args) {
        int[] nums = {1, 1, 1, 2, 3, 3, 4, 4, 5, 6, 7, 8, 8, 8, 9};
        ListNode head = new ListNode(nums);
        Solution2 solution2 = new Solution2();
        ListNode deleteDuplicates = solution2.deleteDuplicates(head);
        System.out.println(deleteDuplicates);
    }
}

Python 代码:

class Solution:
    def deleteDuplicates(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """

        if head is None or head.next is None:
            return head

        dummy = ListNode(-1)
        dummy.next = head
        cur = dummy

        while cur.next and cur.next.next:
            if cur.next.val == cur.next.next.val:
                # 继续往后看,有没有相等的元素
                # del_node 至少删掉它
                del_node = cur.next.next
                while del_node.next and del_node.val == del_node.next.val:
                    del_node = del_node.next
                # 开始删除操作
                cur.next = del_node.next
                del_node.next = None
            else:
                cur = cur.next
        return dummy.next

文章作者: liweiwei1419
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 liweiwei1419 !
评论
 上一篇
「力扣」第 83 题:删除排序链表中的重复元素(简单) 「力扣」第 83 题:删除排序链表中的重复元素(简单)
「力扣」第 83 题:删除排序链表中的重复元素(简单) 链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list; 传送门:删除排序链表中的重复元素。
下一篇 
「力扣」第 61 题:旋转链表(中等) 「力扣」第 61 题:旋转链表(中等)
「力扣」第 61 题:旋转链表(中等) 英文网址:61. Rotate List ; 中文网址:61. 旋转链表 。 链接:https://leetcode-cn.com/problems/rotate-list 我写的题解地址:http
  目录