示例工程【免费下载链接】leetcodeLeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer第 2 版》、《程序员面试金典第 6 版》题解项目地址https://gitcode.com/doocs/leetcode点击查看免费下载LeetCode 237「删除链表中的节点」是一道非常经典的链表面试题它不给你链表的头节点head只给你一个待删除的节点node却要求你完成删除操作。本文将基于 doocs/leetcode 仓库中该题的中文题解与多语言实现深入拆解节点赋值值拷贝 跳过后继这一 O(1) 解法背后的数据结构原理并给出 Python、Java、C、Go、TypeScript、JavaScript、C#、C 八种语言的完整可运行代码帮助你彻底掌握这一无前驱删除技巧同时应对同类变体题型。题目回顾只给你节点不给你 head题目描述非常反常规有一个单链表的head我们想删除其中的一个节点node但无法访问第一个节点head函数入参只有待删除的node本身链表所有节点的值都是唯一的且保证给定的node不是链表中的最后一个节点。同时题目对删除给出了明确的语义界定给定节点的值不应该存在于链表中链表中的节点数应该减少 1node前面所有值的顺序不变node后面所有值的顺序不变。两个官方示例如下输入输出说明head [4,5,1,9],node 5[4,1,9]删除值为 5 的第二个节点head [4,5,1,9],node 1[4,5,9]删除值为 1 的第三个节点约束条件来自原题解文档链表中节点的数目范围是[2, 1000]-1000 Node.val 1000链表中每个节点的值都是唯一的需要删除的节点node是链表中的节点且不是末尾节点。在自定义测试中判题系统会为你构建好整个链表并把node传入函数输出则是调用函数之后的整个链表。为什么这道题不能按常规套路删除常规删除依赖前驱节点在单向链表中标准删除流程是找到待删除节点的前驱节点pre然后执行pre.next pre.next.next将前驱直接指向后继从而把目标节点从链上摘除。仓库中的 203. 移除链表元素 就是这种典型场景题目给你head和val解法维护一个哑节点dummy作为哨兵用pre依次观察后继节点命中目标值即执行pre.next pre.next.next跳过它。这类解法的前提是能拿到头节点、能沿链遍历。本题的陷阱没有前驱可用而本题你只有node本身。单向链表的指针是单向的node知道自己指向谁node.next却不知道谁指向自己因此无法修改前驱的next指针。如果沿用常规思路这道题将无解。这正是本题作为经典面试题的考察点当改前驱这条路被堵死时如何换一个角度完成等价的删除效果核心解法节点赋值值拷贝 跳过后继思路推导原题解文档给出了简洁的思考过程只给定待删结点、没有前驱无法改前驱的next。可将后继的值抄到当前结点再跳过后继效果等同删除。具体而言只需要两步赋值node.val node.next.val—— 把下一个节点的值拷贝进当前节点node.next node.next.next—— 让当前节点跳过后继节点直接指向后继的后继。执行完毕后从调用者视角看当前节点位置的值变成了原来后继的值而原本后继的位置被跳出了链表等价于删除了传入的node。节点数减少 1前后节点的相对顺序均保持不变完全满足题目语义。以head [4,5,1,9]、node 5为例逐步推演初始4 - 5 - 1 - 9待删节点是值为 5 的第二个节点第一步赋值把后继值为 1 的节点的值抄给当前节点节点变为4 - 1 - 1 - 9第二步跳过当前节点的next指向后继的后继链表变为4 - 1 - 9。最终链表中不再存在值 5节点数由 4 减为 3前后顺序保持不变。关于删除的内存语义题目特别强调删除节点并不是指从内存中删除它。因此本解法不需要调用free或delete释放内存。被跳过的那个节点虽然仍残留在堆上但已经不再被链表引用在 Python、Java、Go、C#、JavaScript/TypeScript 等带垃圾回收GC的运行时中它会由 GC 自动回收在 C/C 中LeetCode 判题环境关注的是链表逻辑结构的变化函数内无需手动释放内存。这也解释了为什么仓库中 Solution.c 的实现只做两步指针操作而不含free调用。为什么题目约束恰好保证了该解法的正确性保证node不是尾节点这是本解法成立的前提。若node是尾节点则node.next为null第一步取值就会空指针异常更无从谈跳过后继保证节点值唯一第一步的值拷贝不会产生值冲突确保删除后链表中确实不再存在该值逻辑语义与真正删除一致节点数范围[2, 1000]保证链表中至少有两个节点即任何待删节点都存在合法的后继。多语言实现完整可运行代码以下实现均来自仓库 0237.Delete Node in a Linked List 目录下的Solution.*源文件与题解文档函数签名完全贴合 LeetCode 平台要求不返回任何值原地in-place修改链表。Python3# Definition for singly-linked list. # class ListNode: # def __init__(self, x): # self.val x # self.next None class Solution: def deleteNode(self, node): :type node: ListNode :rtype: void Do not return anything, modify node in-place instead. node.val node.next.val node.next node.next.nextJava/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val x; } * } */ class Solution { public void deleteNode(ListNode node) { node.val node.next.val; node.next node.next.next; } }C/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: void deleteNode(ListNode* node) { node-val node-next-val; node-next node-next-next; } };Go/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ func deleteNode(node *ListNode) { node.Val node.Next.Val node.Next node.Next.Next }TypeScript/** * Definition for singly-linked list. * class ListNode { * val: number * next: ListNode | null * constructor(val?: number, next?: ListNode | null) { * this.val (valundefined ? 0 : val) * this.next (nextundefined ? null : next) * } * } */ /** Do not return anything, modify it in-place instead. */ function deleteNode(node: ListNode | null): void { node.val node.next.val; node.next node.next.next; }JavaScript/** * Definition for singly-linked list. * function ListNode(val) { * this.val val; * this.next null; * } */ /** * param {ListNode} node * return {void} Do not return anything, modify node in-place instead. */ var deleteNode function (node) { node.val node.next.val; node.next node.next.next; };C#/** * Definition for singly-linked list. * public class ListNode { * public int val; * public ListNode next; * public ListNode(int x) { val x; } * } */ public class Solution { public void DeleteNode(ListNode node) { node.val node.next.val; node.next node.next.next; } }C/** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ void deleteNode(struct ListNode* node) { node-val node-next-val; node-next node-next-next; }可以看到无论哪种语言核心逻辑都严格收敛为同一条语句模式先拷贝后继值再跳过后继节点。这也是仓库中 Solution.py、Solution.java 等全部 8 份源码文件与题解文档保持一致的原因。边界条件与注意事项node必须是链表中真实存在的节点题目保证传入的node在链表中因此无需做存在性校验node绝不能是尾节点node.next为null时node.next.val会抛出空指针异常Java/C/C#/Go/TS或AttributeErrorPython正是因为题目保证了这一点代码才可以裸奔式直接访问node.next无需判空值唯一性是语义前提若存在重复值第一步拷贝覆盖可能让删除后链表中不存在该值这一要求无法严格满足不要试图获取head函数签名中根本没有head参数不要在实现里尝试遍历链表定位前驱——那既不可行也不必要注意指针的求值顺序在 C/C/C#/Java 中node.val node.next.val与node.next node.next.next两行顺序不可颠倒。必须先拷贝值再改写next若先改写next则后继指针已丢失第一步就无从拷贝。Python/Go/JS/TS 的实现同样遵循先取值、再跳链的顺序。复杂度分析时间复杂度O(1)。整个删除过程只执行常数次赋值与指针操作与链表长度无关无需遍历空间复杂度O(1)。只使用现有节点和指针不申请任何额外数据结构。这一常数时间删除是本题的核心亮点常规的单链表删除需要 O(n) 遍历找前驱而本题借助值拷贝这一技巧在无法访问前驱的限制下依然做到了 O(1)。同类题型拓展面试题 02.03「删除中间节点」同样的解题模式在仓库的《程序员面试金典》部分也有收录面试题 02.03. 删除中间节点。该题给定单向链表a-b-c-d-e-f中的中间节点c要求将其删除后链表变为a-b-d-e-f——入参同样只有待删节点本身同样保证不是尾节点解法与本题完全一致class Solution: def deleteNode(self, node): node.val node.next.val node.next node.next.next可见无前驱删除是链表题中的高频考察点。掌握了 LeetCode 237 的节点赋值法遇到这类变体可以直接迁移复用。与之形成对比的是前面提到的 203. 移除链表元素当你能拿到head时应优先使用哑节点 前驱遍历的标准删除法而当入参只有节点本身时则应切换到值拷贝 跳过后继这一非常规但极其优雅的技巧。小结LeetCode 237 的独特之处在于只给待删节点、不给头节点导致常规的找前驱、改指针方案不可用解法核心是节点赋值把后继的值拷贝到当前节点再把当前节点的next指向后继的后继两步完成 O(1) 删除该解法成立依赖两个关键前提node非尾节点与节点值唯一二者均由题目约束保证仓库中该题收录了 Solution.py、Solution.java、Solution.cpp、Solution.go、Solution.ts、Solution.js、Solution.cs、Solution.c 共 8 种语言的完整实现并配中文与英文题解可作为刷题与面试复习的可靠参考。赞分享示例工程【免费下载链接】leetcodeLeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer第 2 版》、《程序员面试金典第 6 版》题解项目地址https://gitcode.com/doocs/leetcode点击查看免费下载相关推荐不借助头结点删除链表节点LeetCode 237「节点赋值」解法的原理与多语言实现不借助头结点删除链表节点LeetCode 237「节点赋值」解法的原理与多语言实现 本文围绕 LeetCode 237 题「删除链表中的节点」Delete示例工程InterviewGuide 精选力扣237. 删除链表中的节点——不访问头节点也能 O(1) 删除的替身攻击解法精讲InterviewGuide 精选力扣237. 删除链表中的节点——不访问头节点也能 O 1 删除的替身攻击解法精讲 本篇来自 InterviewGuid教程Czkawka 磁盘清理工具完整教程一次扫描定位重复文件与空文件夹Czkawka 磁盘清理工具完整教程一次扫描定位重复文件与空文件夹 Czkawka 是一款用 Rust 编写的免费开源磁盘清理工具能把你指定的目录一次性扫一桌面应用CLI上一篇3步搞定AmberELEC BIOS配置让复古游戏完美运行下一篇DeFlock地图秒开揭秘ALPR数据经纬度分片加载与缓存设计创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考