js算法题解(第十天)---LeetCode:82. 删除排序链表中的重复元素 II

665 阅读3分钟

「这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战

前言

死磕算法,每天至少一道算法题

昨天咱们讲了删除排序链表中的重复元素

今天咱们来做一下他的升级版

题目

这是leetcode上的第82道题 删除排序链表中的重复元素 II

给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。

难度:中等(摇身一变成中等了)

图片.png

示例 1:

输入:head = [1,2,3,3,4,4,5]
输出:[1,2,5]

思路

第一步:从题目中提取关键字

  • 1.删除原始链表中所有重复数字的节点,只留下不同的数字 。 这就是升级呀,以前好歹我们重复数字还留一个独苗,现在倒好,独苗都给人家拔了

第二步: 分析

  • 1.首先考虑哪些情况没必要往下执行了,如果head为[]或者为[1],那么我们就直接返回就行了,所以链表题的最初的几行代码我们都可以写上,其实有时候这个代码不用写,因为循环的时候会判断,但是我们写上也没啥错呀,我们不用特别追求完美,写自己容易理解的代码就行
if(!head||!head.next){
    return head;
}
  • 2.我们要考虑如果第一个节点和第二个节点就是重复节点要怎么办?所以我们要声明一个假节点,假节点的next指向head,这样我们才能删除第一个节点
let dummy = new ListNode();
dummy.next = head;
// 一定要声明虚拟结点,虚拟结点用于操作链表
let cur = dummy;

这样,基本的框架也就出来了,接下来就是填写框架

var deleteDuplicates = function(head) {
    if(!head||!head.next){
        return head;
    }
    let dummy = new ListNode();
    dummy.next = head;
    let cur = dummy;
    while(判断条件){
        if(){
            // 主要代码部分
        }else{
            // 循环链表必写代码
            cur = cur.next;
        }
        
    }
    return dummy.next;
};

有同学会问,cur为什么指向dummy,而不是head?你要指向了head,怎么改变next指向,也就是你怎么删除第一个节点

  • 3.所以现在就要分析主要逻辑,主要逻辑是什么我们大家很清楚,就是删除重复节点,那肯定要判断两个节点的值是否相同呀,不然怎么删除

因为我们的dummy是没有值的,所以判断条件应该写成

if(cur.next.val === cur.next.next.val){
    
}

所以while的判断条件也就出来了,然后我们在记录一下相等的值,while(while语句一定要注意边界)循环删除

if(cur.next.val===cur.next.next.val){
            // 记录下当前相等的值
            let value = cur.next.val;
            // 注意好边界问题
            while(cur.next&&cur.next.val===value){
                // 此时我们要改变指针的指向,也就是开始删除值
                cur.next = cur.next.next;
            }
        }

所以我们的答案就写出来了

题解

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var deleteDuplicates = function(head) {
    if(!head||!head.next){
        return head;
    }
    let dummy = new ListNode();
    dummy.next = head;
    let cur = dummy;
    while(cur.next&&cur.next.next){
        if(cur.next.val===cur.next.next.val){
            // 记录下当前相等的值
            let value = cur.next.val;
            while(cur.next&&cur.next.val===value){
                // 此时我们要改变指针的指向,也就是开始删除值
                cur.next = cur.next.next;
            }
        }else{
            // 循环结点
            cur = cur.next;
        }
    }
    return dummy.next;
};

总结

写题的时候一定要多考虑几个极端的测试条件,因为算法是不能背诵的,多考虑几个极端条件才能让我们写的题解更加正确✅

参考

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