203.移除链表元素
题意:删除链表中等于给定值 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 输出:[]
思路
如上图所示,目标链表中需要删除 6 ,最终得到一个新链表。
原链表删除
如上图所示,要删除节点 6 ,第一步需要断开节点 3 指向节点 6 的指针。
第二步则是将节点 3 指向节点 6 的下一个节点。
但是有一种特殊情况,即链表头节点为需要删除的目标元素。
这种情况需要将头节点指针后移,直到头节点指向的节点不为需要删除的节点。
代码
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
};
虚拟头节点
在原链表上直接删除有个问题,需要对头节点需要删除的情况做特殊处理。为了统一处理所有节点,可以引入虚拟头节点。
从上图可以看出,再引入虚拟头节点后,所有节点都有一个前置节点,于是所有节点的处理方式都可以统一。
代码
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
};