【Leetcode】82.删除排序链表中的重复元素 II

99 阅读2分钟

leetcode-82.png

这一题跟83题差不多,仅仅是意思差不多,但是处理没有83题那么简单
83题可以不需要dummy节点,处理逻辑也不会很麻烦,但是这一题稍微麻烦一点

双指针解法

因为这里要去除所有一样的节点,只要一样,就要丢
slow这里指向dummy是为了处理刚开始就重复的元素,如果刚开始就重复了,那返回的头节点是什么,应该是dummy.next指向一个不重复的节点,,那么此时就需要slow来做这个衔接的工作了
slow始终指向的就应该是一个独一无二的节点

var deleteDuplicates = function (head) {
    if (!head) return null
    let dummy = new ListNode(-1)
    dummy.next = head
    let slow = dummy, fast = head
    while (fast) {
        while (fast.next && fast.val === fast.next.val) {
            // fast指向当前重复元素的最后一个重复的元素
            fast = fast.next
        }
        // 如果slow的下一个节点是fast,而且fast和fast的下一个节点不相等
        // 移动slow
        if (slow.next === fast) {
            slow = slow.next
        } else {
            // slow的下一节点不是fast,那就证明fast移动了,至少有两个元素相等
            // 那就直接把不相等的(fast.next)给slow衔接上
            slow.next = fast.next
        }
        fast = fast.next
    }
    return dummy.next
};

current指针

总结一些,就是由一般推广到所有
make it simple
首先,肯定是要有一个dummy来指向head的,那么current肯定是要和dummy在一起,这样才能方便处理好第一个节点
既然dummy是在head之前,那么首先就要对比 current.next 还有 current.next.next 上面的 val 是不是相等的,如果是相等的,那么就接着对比,如果不等,就挪动Ï

var deleteDuplicates = function (head) {
    if (!head) return null
    let dummy = new ListNode(-1)
    dummy.next = head
    let current = dummy
    // while的条件是第一个if里面的条件,如果不满足第一个if的条件,会报错
    while (current.next && current.next.next) {
        if (current.next.val === current.next.next.val) {
            // 暂存相等的 val
            let val = current.next.val
            while (current.next && current.next.val === val) {
                // 寻找到不相等的那一个节点,然后指向它
                current.next = current.next.next
            }
        } else {
            // 如果不相等,那么就直接挪动current到下一个节点
            current = current.next
        }
    }
    return dummy.next
};