news 2026/4/30 19:25:31

LeetCode 83/237/82 链表删除问题-盒子模型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 83/237/82 链表删除问题-盒子模型

目录

一、LeetCode 83 移除排序链表中的重复元素(保留一个)

题目核心

核心难点拆解

深度思路(盒子 - 标签 - 纸条模型)

代码实现

易踩坑点 & 底层原理

二、LeetCode 237 删除链表中的节点(无法访问头节点)

题目核心

核心难点拆解

深度思路(盒子 - 标签 - 纸条模型)

代码实现

易踩坑点 & 底层原理

三、LeetCode 82 删除排序链表中的重复元素 II(全删)

题目核心

核心难点拆解

深度思路(盒子 - 标签 - 纸条模型)

代码实现

易踩坑点 & 底层原理

四、跨题深度对比:链表删除的底层逻辑

通用核心原则(所有链表删除题的底层逻辑)

进阶思考


一、LeetCode 83 移除排序链表中的重复元素(保留一个)

题目核心

已排序链表中,重复元素仅保留一个(如1→1→1→2→3→31→2→3)。

核心难点拆解

  1. 为什么不能直接比较curcur.next若让cur初始指向head,比较cur.val == cur.next.val,会导致:
    • 空指针风险:当链表只剩最后一个节点时,cur.nextnull
    • 锚点丢失:cur移动后无法回溯,连续重复节点删不干净(如1→1→1会剩最后一个 1,但中间的重复删不彻底)。
  2. dummy哑节点的底层价值:并非仅为 “避免删头节点”,而是提供一个永远非空的 “根锚点”,让cur可以稳定锚定 “已保留的最后一个不重复节点的前驱”,避免遍历过程中链表断裂。

深度思路(盒子 - 标签 - 纸条模型)

模型元素角色与逻辑
盒子链表节点实体(如 1、1、2),排序特性保证 “重复节点必连续”,无需跨区间检查;
标签-dummy:贴在虚拟盒子(val=0)上,永久锚点,不移动;-cur:贴在 “已保留最后一个不重复节点的前驱盒子”(初始贴dummy),仅在无重复时后移;
纸条删除的本质是修改cur.next(纸条指向),跳过重复盒子;连续重复时cur不移动,持续修改纸条直到无重复。

代码实现

class Solution { public ListNode deleteDuplicates(ListNode head) { // 关键点1:空链表防御(基础边界,所有链表题必加) if (head == null) return null; // 关键点2:dummy哑节点——根锚点,避免头节点重复时的边界问题 ListNode dummy = new ListNode(0, head); ListNode cur = dummy; // cur锚定“已保留节点的前驱”,核心标签 // 关键点3:循环条件双层防御——避免cur.next或cur.next.next为null时的空指针 while (cur.next != null && cur.next.next != null) { if (cur.next.val == cur.next.next.val) { // 难点1:连续重复时,cur不移动,仅修改纸条跳过重复节点 // 例:1→1→1,第一次跳过第二个1,cur仍在dummy,第二次跳过第三个1 cur.next = cur.next.next; } else { // 无重复时,cur才后移——保证cur始终锚定“有效前驱” cur = cur.next; } } // 关键点4:返回dummy.next而非head——head可能已被跳过(如链表全重复时) return dummy.next; } }

易踩坑点 & 底层原理

  • 坑 1:循环条件只写cur.next != null→ 会访问cur.next.next导致空指针;
  • 坑 2:连续重复时移动cur→ 如1→1→1,cur 移到第一个 1 后,后续重复节点无法被跳过;
  • 原理:排序链表的重复是 “连续的”,因此只需 “原地跳过”,无需额外存储 / 回溯。

二、LeetCode 237 删除链表中的节点(无法访问头节点)

题目核心

仅给定待删除节点node(非尾节点),无链表头节点访问权限,要求删除该节点(如4→5→1→9删 5 →4→1→9)。

核心难点拆解

  1. 为什么不能直接删除node节点?链表的节点删除本质是 “修改前驱节点的next”,但本题无表头,无法找到node的前驱节点;且链表节点是 “引用类型”,直接置空node仅会让当前标签失效,链表结构未变。
  2. “偷梁换柱” 的底层逻辑:链表的 “节点价值” 在于valnext,而非节点本身的内存地址 —— 因此可以复用node的内存空间,替换其内容为下一个节点的内容,再删除下一个节点,等价于 “逻辑删除node”。
  3. 为什么题目限定 “非尾节点”?node是尾节点,node.nextnull,无法复制内容,此方法失效(尾节点删除必须依赖前驱节点)。

深度思路(盒子 - 标签 - 纸条模型)

模型元素角色与逻辑
盒子待删除盒子(如 5)、下一个盒子(如 1);复用待删除盒子的 “物理空间”,替换其 “内容”;
标签仅能访问node标签(贴在待删除盒子上),无其他锚点标签;
纸条先复制下一个盒子的val到当前盒子,再修改当前盒子的纸条(node.next),跳过下一个盒子;

代码实现

class Solution { public void deleteNode(ListNode node) { // 关键点1:复制下一个盒子的内容到当前盒子——核心逻辑,偷梁换柱 // 例:node是5,node.next是1 → node.val = 1,此时链表变为4→1→1→9 node.val = node.next.val; // 关键点2:修改纸条,跳过下一个盒子——删除“被复制的下一个盒子” // 例:node.next = 1.next = 9,最终链表4→1→9,等价于删除了原5节点 node.next = node.next.next; } }

易踩坑点 & 底层原理

  • 坑 1:试图直接node = null→ 仅让当前标签失效,链表结构无变化(4→5→1→9 仍存在);
  • 坑 2:忽略 “非尾节点” 限制 → 若 node 是尾节点,node.next.val会空指针;
  • 原理:链表的 “节点标识” 是逻辑上的(val+next),而非物理上的(内存地址),这是 “偷梁换柱” 能成立的核心。

三、LeetCode 82 删除排序链表中的重复元素 II(全删)

题目核心

已排序链表中,所有重复出现的元素全部删除,仅保留无重复的元素(如1→2→3→3→4→4→51→2→51→1→1→2→32→3)。

核心难点拆解

  1. 与 83 题的核心差异:83 题是 “保留一个重复元素”,只需 “逐个跳过”;82 题是 “全删重复元素”,需 “定位重复区间的首尾,批量跳过整个区间”。
  2. 为什么需要temp标签遍历重复区间?若仅用cur单次比较cur.nextcur.next.next,无法处理 “超过 2 个的连续重复”(如1→1→1),必须用temp走到重复区间的最后一个节点,才能精准跳过整个区间。
  3. 循环条件的多层防御cur.next != null && cur.next.next != null是 “基础防御”,temp != null && temp.next != null是 “区间遍历防御”,缺一不可 —— 否则会在重复区间末尾访问null.next导致空指针。

深度思路(盒子 - 标签 - 纸条模型)

模型元素角色与逻辑
盒子重复区间内的所有盒子需 “批量跳过”,无重复的盒子需保留;
标签-dummy:永久根锚点;-cur:贴在 “待判断区间的前驱盒子”(初始贴dummy),仅在无重复时后移;-temp:遍历重复区间的临时标签,找到区间末尾;
纸条cur.next直接指向重复区间的下一个盒子,批量删除整个区间的盒子;

代码实现

class Solution { public ListNode deleteDuplicates(ListNode head) { // 关键点1:双层边界防御——空链表/单节点链表直接返回 if (head == null || head.next == null) return head; // 关键点2:dummy哑节点——避免头节点全重复时的边界问题(如1→1→2) ListNode dummy = new ListNode(0, head); ListNode cur = dummy; // cur锚定“待判断区间的前驱” while (cur.next != null && cur.next.next != null) { // 发现重复区间的起点 if (cur.next.val == cur.next.next.val) { // 关键点3:temp标签遍历重复区间,找到区间最后一个节点 ListNode temp = cur.next; // 区间遍历防御:temp != null 避免temp.next空指针 while (temp != null && temp.next != null && temp.val == temp.next.val) { temp = temp.next; // 走到重复区间的最后一个节点 } // 关键点4:批量跳过整个重复区间——核心逻辑 // 例:1→1→1→2,temp走到第三个1,cur.next = 2,直接跳过所有1 cur.next = temp.next; } else { // 无重复时,cur才后移——保证cur始终锚定“有效前驱” cur = cur.next; } } return dummy.next; } }

易踩坑点 & 底层原理

  • 坑 1:temp循环条件漏写temp != null→ 重复区间末尾temp.next为 null,temp.val空指针;
  • 坑 2:找到重复区间后直接cur.next = cur.next.next→ 仅跳过一个重复节点,无法处理多重复(如 1→1→1 仍会剩一个 1);
  • 原理:排序链表的重复区间是 “连续的”,因此只需一次遍历找到区间末尾,即可批量删除,时间复杂度仍为 O (n)。

四、跨题深度对比:链表删除的底层逻辑

维度83 题(重复留一)237 题(指定节点删除)82 题(重复全删)
核心策略逐个跳过重复节点偷梁换柱(内容替换)批量跳过重复区间
锚点依赖依赖 dummy 做根锚点无锚点(仅目标节点)依赖 dummy 做根锚点
空指针防御双层循环条件无(题目限定非尾节点)双层循环 + 区间遍历防御
核心难点连续重复时 cur 不移动理解 “节点逻辑删除”定位重复区间的首尾
底层原理排序链表的连续性链表节点的引用特性排序链表的区间连续性

通用核心原则(所有链表删除题的底层逻辑)

  1. 锚点优先:只要涉及 “删除头节点” 或 “前驱节点不可知”,优先用dummy哑节点做根锚点,避免链表断裂;
  2. 标签不碰原始锚点:始终用cur/temp等临时标签移动,dummy/head等原始锚点仅做初始定位;
  3. 删除本质是改纸条:所有删除操作均不销毁节点(物理删除),而是修改next指向(逻辑删除);
  4. 边界防御前置:所有链表题先处理 “空链表 / 单节点链表”,避免后续循环的空指针。

进阶思考(深度延伸)

  • 若链表未排序,83/82 题该如何修改?→ 需要用哈希表记录已出现的 val,遍历链表时跳过重复值(时间 O (n),空间 O (n));
  • 237 题若允许删除尾节点,该如何处理?→ 必须遍历链表找到尾节点的前驱(时间 O (n)),或改用双向链表(空间换时间)。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/27 0:22:01

Blender Python API入门指南:快速掌握3D自动化编程

Blender Python API入门指南:快速掌握3D自动化编程 【免费下载链接】blender Official mirror of Blender 项目地址: https://gitcode.com/gh_mirrors/bl/blender 还在为重复的3D建模任务感到困扰吗?想通过代码提升工作效率却不知从何开始&#x…

作者头像 李华
网站建设 2026/4/23 11:19:35

开源UI组件库终极指南:如何快速构建跨平台移动应用

在移动互联网时代,开发多平台应用已成为标配需求。开源UI组件库作为开发者的得力助手,能够显著提升开发效率和质量。Wot Design Uni作为一款基于UniApp框架的开源UI组件库,为开发者提供了完整的解决方案,帮助快速构建高质量的移动…

作者头像 李华
网站建设 2026/4/24 15:00:46

CopilotForXcode插件开发全攻略:从零构建智能编程助手

CopilotForXcode插件开发全攻略:从零构建智能编程助手 【免费下载链接】CopilotForXcode The missing GitHub Copilot, Codeium and ChatGPT Xcode Source Editor Extension 项目地址: https://gitcode.com/gh_mirrors/co/CopilotForXcode CopilotForXcode作…

作者头像 李华
网站建设 2026/4/20 17:52:42

TWiLight Menu++ 终极使用指南:从入门到精通的高效配置方案

TWiLight Menu 终极使用指南:从入门到精通的高效配置方案 【免费下载链接】TWiLightMenu DSi Menu replacement for DS/DSi/3DS/2DS 项目地址: https://gitcode.com/gh_mirrors/tw/TWiLightMenu TWiLight Menu 是一个功能强大的 DSi 菜单增强工具和跨平台游戏…

作者头像 李华
网站建设 2026/4/26 9:22:06

PLabel 5步安装指南:快速搭建半自动图像标注系统

PLabel 5步安装指南:快速搭建半自动图像标注系统 【免费下载链接】PLabel 半自动标注系统是基于BS架构,由鹏城实验室自主研发,集成视频抽帧,目标检测、视频跟踪、ReID分类、人脸检测等算法,实现了对图像,视…

作者头像 李华