解法一:双指针法
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func deleteDuplicates(head *ListNode) *ListNode {
// 有可能头节点就重复了,因此构造虚拟节点,方便操作
// 题目说了 -100 <= node.val <= 100,所以用 -101 作为虚拟头节点值
dummy := &ListNode{
Val: -101,
Next: head,
}
slow, fast := dummy, head
for fast != nil{
if fast.Next != nil && fast.Next.Val == fast.Val{
// 发现有重复元素,跳过这一段相同的节点
for fast.Next != nil && fast.Next.Val == fast.Val{
fast = fast.Next
}
// 此时fast走到了这一段重复元素的最后一个节点,需要全部删除,所以再走一步
fast = fast.Next
// slow.Next此时仍指向fast一开始的位置,即这一段重复元素的第一个节点
// 直接断开与这一段的连接
slow.Next = nil
}else{
// 不重复节点,接到slow后面
slow.Next = fast
fast = fast.Next
slow = slow.Next
}
}
return dummy.Next
}
解法二:分解链表
将原链表分解为两条链表,一条链表存放不重复的节点,另一条链表存放重复的节点,返回不重复的这条链表即为答案
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func deleteDuplicates(head *ListNode) *ListNode {
// 题目说了 -100 <= node.val <= 100,所以用 -101 作为虚拟头节点值
dummyDup := &ListNode{
Val: -101,
Next: head,
}
dummyUniq := &ListNode{
Val: -101,
Next: head,
}
pDup, pUniq := dummyDup, dummyUniq
p := head
for p != nil{
if (p.Next != nil && p.Next.Val == p.Val) || (p.Val == pDup.Val){
pDup.Next = p
pDup = pDup.Next
}else{
pUniq.Next = p
pUniq = pUniq.Next
}
p = p.Next
}
// 切断新链表末尾与原链表剩余节点的连接
pDup.Next = nil
pUniq.Next = nil
return dummyUniq.Next
}