移除链表元素

72 阅读1分钟

203.移除链表元素

力扣题目链接(opens new window)

题意:删除链表中等于给定值 val 的所有节点。

示例 1: 输入:head = [1,2,6,3,4,5,6], val = 6 输出:[1,2,3,4,5]

示例 2: 输入:head = [], val = 1 输出:[]

示例 3: 输入:head = [7,7,7,7], val = 7 输出:[]

思路

截屏2025-08-27 15.46.44.png

如上图所示,目标链表中需要删除 6 ,最终得到一个新链表。

原链表删除

截屏2025-08-27 16.59.53.png 如上图所示,要删除节点 6 ,第一步需要断开节点 3 指向节点 6 的指针。

第二步则是将节点 3 指向节点 6 的下一个节点。

但是有一种特殊情况,即链表头节点为需要删除的目标元素。

截屏2025-08-27 17.02.21.png 这种情况需要将头节点指针后移,直到头节点指向的节点不为需要删除的节点。

代码

function removeElements(head: ListNode | null, val: number): ListNode | null {
    // 处理头节点需要删除情况
    while(head && head.val === val) {
        head = head.next
    }

    let cur = head
    while(cur && cur.next !== null) {
        if(cur.next.val === val) {
            const mid = cur.next.next
            cur.next = mid
        } else {
            cur = cur.next
        }
    }

    return head
};

虚拟头节点

在原链表上直接删除有个问题,需要对头节点需要删除的情况做特殊处理。为了统一处理所有节点,可以引入虚拟头节点。

截屏2025-08-27 17.15.22.png

从上图可以看出,再引入虚拟头节点后,所有节点都有一个前置节点,于是所有节点的处理方式都可以统一。

代码

function removeElements(head: ListNode | null, val: number): ListNode | null {
    // 设置虚拟头节点
    let dummyHead = new ListNode(0, head)

    let cur = dummyHead

    while(cur && cur.next) {
        if(cur.next.val === val) {
            const mid = cur.next.next
            cur.next = mid
        } else {
            cur = cur.next
        }
    }

    return dummyHead.next
};