LeetCode(82+83):删除排序链表中的重复元素

入门版(83题)

题目描述

LeetCode(82+83):删除排序链表中的重复元素

方案1、哈希表+快慢指针(空间复杂度较高)

解题思路

遍历链表,检查当前节点值是否存在于集合中

  • 若存在,令慢指针的next指向快指针的next,快指针向前走,慢指针原地不动
  • 若不存在,则将其加入集合中,快慢指针都向前走

代码实现(Javascript)

var deleteDuplicates = function(head) {
    if(!head){
        return null
    }
    var s = new Set()
    var p = head
    var prev = p
    while(p!==null){
        if(s.has(p.val)){
            prev.next = p.next
            let temp = p
            p = p.next
            delete temp
        }else{
            s.add(p.val)
            prev = p
            p = p.next
        }
    }
    return head
};

方案2、迭代(时间复杂度较高)

解题思路

如果我们不希望开辟额外的空间,就只能通过在迭代中 加入内层循环,来删除重复元素,思路如下:
使用指针cur,从头开始遍历链表
若下一个节点值等于当前节点值,则通过内层循环和一个新的指针inner,遍历到 下一个非重复值的节点中
然后让当前节点的next 直接指向inner(丢弃所有重复节点)
然后cur继续向前走

代码实现(Javascript)

var deleteDuplicates = function(head) {
    if(!head){
        return null
    }
    
    var cur = head

    while(cur){
        if(cur.next && cur.val === cur.next.val){
            let value = cur.val
            let inner = cur
            while(inner && inner.val === value){
                inner = inner.next
            }
            cur.next = inner
        }
        
        cur = cur.next
    }

    return head
};

进阶版(82题)

题目描述

LeetCode(82+83):删除排序链表中的重复元素

解题思路:快慢指针

这道题与上一道题的区别在于:要删除所有重复出现过的元素(上一题是保留一个重复出现的元素)
因此,可能会出现链表头节点被丢弃的情况
所以,我们要构造一个虚拟的头节点node,让node的next指向头节点,并让初始的慢指针指向node
最后将node.next作为返回结果

代码实现(Javascript)

var deleteDuplicates = function(head) {
    var node = new ListNode(-1)
    node.next = head

    var slow = node
    var fast = head

    while(fast){
        if(fast.next && fast.next.val === fast.val){
            let value = fast.val
            while(fast && fast.val === value){
                fast = fast.next
            }
            slow.next = fast
        }else{
            slow = fast
            fast = fast.next
        }
    }

    return node.next
};