入门版(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题)
题目描述
解题思路:快慢指针
这道题与上一道题的区别在于:要删除所有重复出现过的元素(上一题是保留一个重复出现的元素)
因此,可能会出现链表头节点被丢弃的情况
所以,我们要构造一个虚拟的头节点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
};