LC203 leetcode.cn/problems/re…
解法一
错误示例
while (cur!=null){
if (cur.next.val==val) cur.next=cur.next.next;
cur=cur.next;
}
乍一看没问题 但连续两个目标值 就会跳过一个
完整示例
public class LC203 {
/**
* Definition for singly-linked list node.
*/
public static class ListNode {
int val; // 节点的值
ListNode next; // 指向下一个节点的引用
// 无参构造函数
ListNode() {}
// 仅初始化节点值的构造函数
ListNode(int val) {
this.val = val;
}
// 初始化节点值和下一个节点引用的构造函数
ListNode(int val, ListNode next) {
this.val = val;
this.next = next;
}
}
/**
* 删除链表中等于给定值 val 的所有节点。
*
* @param head 链表的头节点
* @param val 要删除的节点值
* @return 处理后的链表头节点
*/
public static ListNode removeElements(ListNode head, int val) {
// 处理头部连续的目标值
while (head != null && head.val == val) {
head = head.next;
}
// 如果链表为空,返回 null
if (head == null) return null;
ListNode cur = head;
// 遍历并处理非头部的节点
while (cur != null && cur.next != null) {
if (cur.next.val == val) {
cur.next = cur.next.next;
} else {
cur = cur.next;
}
}
return head;
}
/**
* 打印链表中的所有节点值。
*
* @param head 链表的头节点
*/
public static void printList(ListNode head) {
ListNode current = head;
while (current != null) {
System.out.print(current.val + " -> ");
current = current.next;
}
System.out.println("null");
}
public static void main(String[] args) {
// 创建链表节点
ListNode node1 = new ListNode(1);
ListNode node2 = new ListNode(2);
ListNode node3 = new ListNode(2);
ListNode node4 = new ListNode(1);
// 组装链表
node1.next = node2;
node2.next = node3;
node3.next = node4;
// 打印原始链表
System.out.print("Original List: ");
printList(node1);
// 删除值为 2 的节点
ListNode listNode = removeElements(node1, 2);
// 打印处理后的链表
System.out.print("Processed List: ");
printList(listNode);
}
}
解法二 虚拟头节点
public static ListNode removeElements(ListNode head, int val) {
// 如果链表为空,直接返回 null
if (head == null) return null;
// 创建一个虚拟头节点,指向链表的头节点
ListNode dummyNode = new ListNode(0, head);
ListNode cur = dummyNode;
// 遍历链表,删除节点值等于 val 的节点
while (cur != null && cur.next != null) {
if (cur.next.val == val) {
cur.next = cur.next.next;
} else {
cur = cur.next;
}
}
// 返回处理后的链表头节点
return dummyNode.next;
}
相比解法一 不用考虑头节点情况
解法三 递归
非常巧妙
public ListNode removeElements(ListNode head, int val) {
// 如果链表为空,直接返回 null
if (head == null) {
return null;
}
// 递归处理链表的下一个节点
head.next = removeElements(head.next, val);
// 如果当前节点的值等于要移除的值,则跳过当前节点,返回下一个节点
if (head.val == val) {
return head.next;
} else {
// 否则,保留当前节点,返回当前节点
return head;
}
}
f (head == null) { return null; }
一是指head本身 二是指递归后的head