[路飞]_leetcode刷题_删除排序链表中的重复元素 II

137 阅读2分钟

「这是我参与11月更文挑战的第4天,活动详情查看:2021最后一次更文挑战

做这一题之前,先做一题类似的,简单的一点的

题目_删除排序链表中的重复元素

存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除所有重复的元素,使每个元素 只出现一次 。

返回同样按升序排列的结果链表。

思路:

链表题做多了,这题直觉就是遍历链表,判断当前节点与后一个节点的值,如果相等,则将后一个节点的指针给当前节点即可删除重复节点。

但是呢要注意,如果当前做了删除操作,不要急于让链表往下走,要继续从当前节点遍历,否则就会删不干净。

代码:

/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var deleteDuplicates = function(head) {
    if(head == null || head.next == null){
        return head;
    }
    let cur = head;
    while(cur){
        // 这里注意,如果做了删减动作了,就不要让cur向前走,继续从当前cur去循环
        if(cur.next && cur.val == cur.next.val){
            cur.next = cur.next.next;
        }else{
            cur = cur.next
        }
    }
    return head;
};

然后我们再做进阶的_删除排序链表中的重复元素 II

存在一个按升序排列的链表,给你这个链表的头节点 head ,请你删除链表中所有存在数字重复情况的节点,只保留原始链表中 没有重复出现 的数字。

返回同样按升序排列的结果链表。

思路:

这题就是上一题的升级版,不仅要删除重复元素,而且要将所有重复元素都删除,那么头节点也会有可能被删除,所以我们需要创建一个伪头节点来进行遍历,方便删除头节点。

另外,遇到开始要删重复节点的时候,我们要将重复节点删完之后,再让链表往下走。我这里是用一个标识hasDuplicate来标记是否有重复元素,遇到开始删除重复节点的时候,则让hasDuplicate=true,当将连续的重复节点的最后一个删除掉的时候,则将hasDuplicate=false,只有当前没有重复元素,且hasDuplicate=false的时候,才让链表往后走

具体代码如下

/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var deleteDuplicates = function(head) {
    if(head == null || head.next == null){
        return head;
    }
    let fakeNode = new ListNode(0,head);
    let cur = fakeNode;
    let hasDuplicate = false;
    while(cur){
        if(cur.next && cur.next.next && cur.next.val == cur.next.next.val){
            cur.next = cur.next.next;
            hasDuplicate = true;
        }else if(hasDuplicate){
            cur.next = cur.next.next;
            hasDuplicate = false;
        }else{
            cur = cur.next;
        }
    }
    return fakeNode.next;
};