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

105 阅读2分钟

题目

给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。

 

示例 1:

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

示例 2:

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

 

提示:

  • 链表中节点数目在范围 [0, 300] 内
  • -100 <= Node.val <= 100
  • 题目数据保证链表已经按升序 排列

题解

由于题目中给定的链表时排好序的,因此重复的元素在链表中的位置都是相邻连续的,只需要对链表进行一次遍历,就可以删除重复的元素,注意链表的头结点可能被删除,因此需要一个额外的哑结点(dummy) 指向链表的头结点

具体流程如下:

  1. 初始化时,dummy指针指向链表的头结点,声明cur = dummy指向链表的哑结点。
  2. 对链表遍历,如果 cur.next.val === cur.next.next.val, 说明元素重复,就需要将cur.next自己和它之和的拥有相同元素的值的节点全部删除,先用 x记录cur.next.val, 随后不断地将cur.next从链表中移除,直到cur.next为空节点或者其元素值不等于x, 此时,链表中所有为元素x的节点全部删除。
  3. 如果当前 cur.next.val !== cur.next.next.val, 即元素不相同, 那说明链表中只有一个元素值为cur.next的节点,直接将 cur 指向 cur.next
  4. 遍历完整个链表后,返回链表的哑结点的下一个节点dummy.next即可

代码

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var deleteDuplicates = function(head) {
    
    if (head == null) return head;
    // 由于链表中头结点可能被删除,所以需要额外使用一个哑结点,指向头结点
    const dummy = new ListNode(-1, head);

    let cur = dummy;
    
    // 一开始cur.next指向head, cur.next.next 指向 head.next;
    while(cur.next && cur.next.next) {
        // 说明下一个节点和下下个节点重复,需要全部删除
        if (cur.next.val === cur.next.next.val) {
            const x = cur.next.val;
            // 继续遍历,看下下下节点是否和下下节点重复,重复就删除
            while(cur.next && cur.next.val === x) {
                cur.next = cur.next.next;
            }
        } else {
            cur = cur.next;
        }
    }

    return dummy.next;
};

原题链接

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