【Leetcode】82. 删除排序链表中的重复元素 II

215 阅读2分钟

题目描述

在这里插入图片描述

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

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

题解

没做过【Leetcode】83. 删除排序链表中的重复元素 的建议先做83题,那边是用了双指针法,把重复元素删除。

本题是直接把出现重复元素的节点,一个不剩的删除。需要用到三指针。

一个dumyhead放在head的前面,pre指向dummyhead,mid指向head,cur指向head.next。三个指针,老样子,如果mid和cur这前面这两兄弟如果没有发现重复元素,则三指针右移。

如果发现重复,怎么删除呢?记录下出现重复元素的值,即为val,让cur指针一直移动到值不为val的地方,mid跟在cur的前一个位置,pre不动(如果cur一直移动到了null,那就更好了,直接让pre指向null,就删除完毕)。

之后就是正常的删除操作,让mid指向null,再回到cur,这样重复序列的右边就断连了,让pre.next指向cur,重复序列的左边就断连了,然后让cur再右移一位,摆好前中后三指针的位置。

执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户

内存消耗:38.1 MB, 在所有 Java 提交中击败了5.73%的用户

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode head) {
        if (head == null || head.next == null)
            return head;
        ListNode dummyHead = new ListNode(-1);
        dummyHead.next = head;
        ListNode pre = dummyHead;
        ListNode mid = head;
        ListNode cur = head.next;
        while (mid != null && cur != null) {
            if (mid.val != cur.val) { 
                pre = pre.next;
                mid = mid.next;
                cur = cur.next;
            }
            else {
                int val = cur.val;
                while (cur != null && cur.val == val) {
                    mid = mid.next;
                    cur = cur.next;
                }

                if (cur == null) {
                    pre.next = null;
                }
                else {  // cur != null
                    mid.next = null;
                    mid = cur;
                    cur = cur.next;
                    pre.next = mid;
                }
            }
        }
        return dummyHead.next;
    }
}