删除链表的节点

97 阅读2分钟

题目描述

给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。

返回删除后的链表的头节点

示例 1:

输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.

示例 2:

输入: head = [4,5,1,9], val = 1
输出: [4,5,9]
解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.

思考

  1. 本题有两种方法去解决,分别是采用虚拟头结点和不采用虚拟头结点。
  2. 采用虚拟头结点的方式:不需要考虑考虑删除的节点是否是头结点。
  3. 不采用虚拟头结点的方式:需要分删除节点是头结点和不是头结点两种情况。

思路

这里以链表 1 4 2 4 来举例,移除元素4。

image.png

我们要操作的节点是目标节点的前一个节点和后一个节点.

不采用虚拟头结点(需要区分目标节点是否是头结点)

image.png 当目标节点是头结点时,进行head=head.next,即:

image.png

当目标节点不是头结点时,进行cur.next=cur.next.next,即:

image.png

设置虚拟头结点

image.png

这时,移除头结点便与移除其他节点操作一致了!

代码

虚拟头结点

/**
 * 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) {
    var virtualNode=new ListNode("a"); //创建虚拟头结点
    virtualNode.next=head;//将虚拟头结点变为链表的第一个节点
    let cur=virtualNode; //指针指向链表第一个节点
    //当cur.next 不为空时
    while(cur.next!=null){
        //判断下一个节点是否是目标节点
        if(cur.next.val==val){
            cur.next=cur.next.next; //删除目标节点
        }else{
            cur=cur.next; //否则移动指针
        }
    }

    return virtualNode.next;  //返回链表
};

不使用虚拟头结点

/**
 * 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) {
    let cur=head;
    while(cur!=null&&cur.next!=null){
        //判断head节点是否是目标节点
        if(cur.val==val){
            head=head.next; //移动head节点
            cur=head;
        }else{
           
            if(cur.next.val==val){
                cur.next=cur.next.next; //操作目标节点的前一个节点和后一个节点。
            }else{
                cur=cur.next;
            }
        }
    }
    return head;
};

结果

image.png

总结

  1. 要知道操作的节点是目标节点的前一个后一个.
  2. 不使用虚拟头结点时,需要区分目标节点是否是head节点的情况。