「前端刷题」82. 删除排序链表中的重复元素 II

287 阅读1分钟

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

题目

链接:leetcode-cn.com/problems/re…

存在一个按升序排列的链表,给你这个链表的头节点 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
  • 题目数据保证链表已经按升序排列

解题思路

思路1

下一个和下一个的下一个比, 如果相同, 记录该值
只要下一个值和这值一样就 把当前的下一个指针 指向下一个的下一个, 否则移动当前位置

image.png

/**
 * 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) {
    let node = new ListNode(-1)
    node.next = head
    let cur = node
    while (cur.next && cur.next.next) {
        if (cur.next.val === cur.next.next.val){ // 重复
            let val = cur.next.val
            while(cur.next && cur.next.val === val){
                cur.next = cur.next.next
            }
        } else { // 不重复
            cur = cur.next
        }
    }
    return node.next
};

思路2

先走一遍, 用set记录重复的元素, 再走一遍, 只要set中存在的就跳过

var deleteDuplicates = function(head) {
    let node = new ListNode(999)
    node.next = head
    let cur = node
    let set = new Set()
    while(cur && cur.next){
        if (cur.val === cur.next.val){
            set.add(cur.val)
            cur.next = cur.next.next
        } else {
            cur = cur.next
        }
    }
    cur = node
    while(cur && cur.next){
        if (set.has(cur.next.val)){
            cur.next = cur.next.next
        } else {
            cur = cur.next
        }
    }
    return node.next
};

思路3

没看清楚题目是排序链表,写的是非排序链表的算法,多遍历了一遍,多用了O(n)的空间

/**
 * 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 || head.next === null) return head;

    // 遍历一遍,将所有的值放到 map 中并统计出现次数
    let tempHead = head, map = new Map();
    while(tempHead) {
        if(map.has(tempHead.val)) {
            map.set(tempHead.val, map.get(tempHead.val) + 1);
        } else {
            map.set(tempHead.val, 1);
        }
        tempHead = tempHead.next;
    }

    // 去掉头部的重复元素
    while(head && map.get(head.val) > 1) head = head.next;

    // 去掉非头部的重复元素
    tempHead = head;
    while(tempHead && tempHead.next) {
        if(map.get(tempHead.next.val) > 1) {
            tempHead.next = tempHead.next.next;
        } else {
            tempHead = tempHead.next;
        }
    }
    return head;
};