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

46 阅读1分钟

image.png

解法一:双指针法

/**
 * 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
}