持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第14天,点击查看活动详情
关于算法系列已更新部分文章,后续会陆续增加内容:
【1】 算法之用动态规划实现斐波那契数列
【2】 算法之双指针法的应用
【3】 算法之链表的含义
题目描述
已知一个链表的头节点 head 和一个整数 val ,删除链表中所有满足 Node.val == val 的节点,并返回新的头节点。
示例 1:
输入:head = [1,2,6,3,4,5,6], val = 6
输出:[1,2,3,4,5]
示例 2:
输入:head = [7,7,7,7], val = 7
输出:[]
注:在 leetcode 中不需要单独定义节点和链表,在注释中可以看到提供了定义部分的实现方式,所以只负责功能点的实现即可。
关于链表
在前面介绍过关于链表的一些基本理念,一个链表是由0到多个结点连接而成的,每个节点都有自己的结构,包括数据域和指针域。
移除链表元素是链表的基本操作之一,除此之外还有插入修改、查找、删除等基于链表的常规操作。
如下图所示,删除元素实际上是一个断开连接,重新连接的过程:
被删除节点的前一个节点的next,不再存储被删除节点的地址,而是被删除节点的下一个节点的地址
代码实现
关键点:
- 设置一个虚拟的头节点,这样当删除的是头节点的时候就不需要额外进行操作
- 删除时需要遍历整个链表,通过循环定位到被删除的元素。初始位置是虚拟头节点
- 因为删除操作需要改变上一个元素的next,所以判断的条件是cur.next.val === val,即当前节点的下一个节点的值和要删除的值相等
- 当找到目标元素
cur时,将其 next 的指向改变(cur.next = cur.next.next),continue 进入下一次循环(可能还有待删除的节点) - 当还未找到时,继续移动指针(cur = cur.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
* @param {number} val
* @return {ListNode}
*/
var removeElements = function(head, val) {
const ret = new ListNode(0, head);
let cur = ret;
while(cur.next) {
if(cur.next.val === val) {
cur.next = cur.next.next;
continue;
}
cur = cur.next;
}
return ret.next;
};