给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == 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
输出:[]
思路
这题就是基本的链表删除节点问题。有两种不同的写法。
主要注意的是链表的头节点如何进行删除。
方法一:添加虚拟头节点的方式,可以采用统一的删除节点方式。
方法二:单独处理头节点,需要单独对头节点进行处理。
代码
虚拟头节点
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
// 添加虚拟节点方式
// 定义一个虚拟头节点,指向 head
ListNode dummy = new ListNode(-1,head);
// 指向虚拟头节点
ListNode pre = dummy;
ListNode cur = head;
// 遍历 链表
while (cur != null) {
// 链表节点的值与目标值相等
if (cur.val == val) {
// 将虚头节点指针指向下下个位置(跳过一个)
pre.next = cur.next;
}else {
pre = cur;
}
// 指向下一个节点
cur = cur.next;
}
return dummy.next;
}
}
单独处理头节点
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode removeElements(ListNode head, int val) {
// 使用 while 而不是 if 的原因是,很有可能链表的前几个节点都满足条件
// 如果是 if 的话,就只会删除一个头节点
while (head != null && head.val == val) {
// 删除头节点,指向下一个节点
head = head.next;
}
// 判断临界条件
if (head == null) {
return head;
}
// 临时节点,代替 head 进行遍历链表
ListNode pre = head;
// 下一个节点位置,每次判断下一个节点是否满足条件
ListNode cur = head.next;
while (cur != null) {
// 满足条件,进行删除节点
if(cur.val == val) {
pre.next = cur.next;
}else {
pre = cur;
}
cur = cur.next;
}
// 返回头节点
return head;
}
}