LeetCode JavaScript实现 链表删除节点(重复指定等情况) 题型汇总

Posted YuLong~W

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode JavaScript实现 链表删除节点(重复指定等情况) 题型汇总相关的知识,希望对你有一定的参考价值。

面试题 02.01. 移除重复节点

原题链接:面试题 02.01. 移除重复节点
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var removeDuplicateNodes = function(head) {
  
};

解题思路:

①哈希表法

  • 利用哈希表依次存储结点
  • 用set.has()方法判断是否重复,如果重复通过指向进行删除,并后移
  • 不重复则通过set.add()存储,并后移
var removeDuplicateNodes = function(head) {
    //利用哈希
    if(head==null){
        return head;
    }
    var set=new Set();
    set.add(head.val);

    var prev=head;      //head赋给prev
    var curr=head.next; //head.next赋给curr

    while(curr!=null){
        if(set.has(curr.val)){ //如果当前结点重复
            prev.next=curr.next; //让prev的next指向curr的next 进行删除
            curr=curr.next; //curr后移
        }else{
            set.add(curr.val); //第一次出现 ,存储到set里
            prev=prev.next;    //prev和curr均后移
            curr=curr.next;
        }
    }
    return head;
};

②利用双指针法

  • 声明p、q指针,分别指向head和p
  • 将p指针的位置先固定,不断移动q指针进行扫描与p的值比较,相同则删除 ,否则q指向后移
  • 一轮循环完后,让p向后移,判断下一个结点
  • 时间复杂度较高,执行效率慢
var removeDuplicateNodes = function(head) {
    //双指针
    var p=head;
    while(p!=null){
        var q=p; //将p指针赋给q
        while(q.next!=null){
            if(q.next.val==p.val){ //如果后面的q有和固定的p有重复
                q.next=q.next.next; //删除重复
            }else{
                q=q.next;
            }
        }
        p=p.next; //让p向后移,判断下一个结点
    }
    return head;
};

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

原题链接:83. 删除排序链表中的重复元素
在这里插入图片描述

/**
 * 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) {
 
};

解题思路:

注意: 与上题的不同点在于,该链表已经按升序排列,所以重复元素一定相邻,比无序排列的链表删除重复元素简单

  • 让p指针指向head 并且判断p的val和p.next.val是否相等
  • 如果相等则为重复并删除 , 否则,p指针指向下一个元素
var  deleteDuplicates = function (head) {
    //链表为空
    if (head == null) {
        return head;
    }
    //链表不为空
    var p =head;
    while (p.next != null) {
        if (p.val == p.next.val) {
            p.next = p.next.next;  //删除重复元素
        } else {
            p = p.next; //指针指向后移
        }
    }
    return head;
};

203. 移除链表元素

原题链接:203. 移除链表元素
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * function ListNode(val, next) {
 *     this.val = (val===undefined ? 0 : val)
 *     this.next = (next===undefined ? null : next)
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} val
 * @return {ListNode}
 */
var removeElements = function(head, val) {

};

方法一:迭代法
需要判断头结点是否为删除的结点

var removeElements = function(head, val) {
    //头结点为空
    if (head == null) return head;
    //头结点为要删除的结点 或者新的头结点也要被删除
    while (head != null && head.val == val) {
        head = head.next;
    }
    var curr = head;
    //确保当前结点不为空,并且当前结点后还有结点
    while (curr != null && curr.next != null) {
        if (curr.next.val == val) {
            curr.next = curr.next.next;
        } else {
            curr = curr.next;
        }
    }
    return head;
};

方法二 :(与一类似)
添加一个虚拟头结点

var removeElements = function(head, val) {
    //头结点为空
    if (head == null) return head;
    //创建一个结点null,指向head结点 确保此时的head结点不是头结点
    //目的是为了确保head结点不是要删除的结点
    var list = new ListNode(null, head);
    var curr = list;
    while (curr.next != null) {
        if (curr.next.val == val) {
            curr.next = curr.next.next;
        } else {
            curr = curr.next;
        }
    }
    return list.next;
};

方法三:递归
终止条件是head为空。 head不为空时递归进行操作

var removeElements = function(head, val) {   
    if(head==null) return head;
    head.next=removeElements(head.next,val);
    if(head.val==val){
        return head=head.next;
    }else{
        return head;
    }
};

具体动画详解参考:动画演示 迭代法 #203 移除链表元素

剑指 Offer 18. 删除链表的节点

原题链接:剑指 Offer 18. 删除链表的节点
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @param {number} val
 * @return {ListNode}
*/
var deleteNode = function (head, val) {

};

先判断头结点是否为要删除,然后定义currNode指向头结点,并判断currNode.next的val值

var deleteNode = function (head, val) {
    if (head.val === val) //在链表头部删除
        return head.next;
    var currNode=head;
    while (currNode.next.val !== val && currNode !== null) {
        currNode = currNode.next;
    }
    currNode.next = currNode.next.next;
    return head;
};

237. 删除链表中的节点 / 面试题 02.03. 删除中间节点

原题链接:删除链表中的节点
在这里插入图片描述
原题链接:面试题 02.03. 删除中间节点
在这里插入图片描述

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} node
 * @return {void} Do not return anything, modify node in-place instead.
 */
var deleteNode = function(node) {

};

题目的坑!!!注意看题!

参数没有头结点 ,所以不能遍历链表找待删除的结点

要删除的结点是链表的一部分而不是结点的val值

var deleteNode = function(node) {
    //直接删除当前结点的值,并让下一结点的值取代
    node.val=node.next.val
    node.next=node.next.next
};

以上是关于LeetCode JavaScript实现 链表删除节点(重复指定等情况) 题型汇总的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode JavaScript实现 回文链表(回文字符串) 题型汇总(双指针解法)

LeetCode JavaScript实现 链表删除节点(重复指定等情况) 题型汇总

[JavaScript 刷题] 链表 - 链表的中间结点, leetcode 876

[JavaScript 刷题] 链表 - 相交链表, leetcode 160

[JavaScript 刷题] 链表 - 相交链表, leetcode 160

[JavaScript 刷题] 链表 - 反转链表, leetcode 206