当前位置: 首页 > news >正文

Hot 100 --- 两两交换链表中的节点

本文概览:本文以LeetCode经典题目"两两交换链表中的节点"为例,重点讲解如何通过哑节点解决新头节点问题,如何用prevfirstsecond三个指针完成两两交换,以及如何判断循环结束条件


一、题目

二、题目分析

给定一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点

目标:交换节点本身,而不是只交换节点值

核心难点:链表节点交换本质上是指针重连,容易断链或者丢失后续节点

这道题主要有三个问题需要解决:

  1. 怎么返回新的头节点?
  2. 怎么交换两个相邻节点?
  3. 循环什么时候结束?

思路概览

Java实现代码如下

public ListNode swapPairs(ListNode head) { if (head == null || head.next == null) { return head; } // 创建哑节点 ListNode dummy = new ListNode(0, head); // 初始化前指针 ListNode prev = dummy; // 交换后面两个节点 ListNode first; ListNode second; // 交换节点 while (prev.next != null && prev.next.next != null) { first = prev.next; second = first.next; // 交换节点 prev.next = second; first.next = second.next; second.next = first; // 更新前指针 prev = first; } return dummy.next; }

思路简要说明

  1. 哑节点解决头节点变化:交换第一对节点后,新的头节点会变成原来的第二个节点,所以用dummy指向原头节点,最后返回dummy.next

  2. 三个指针完成交换prev指向当前要交换的一对节点的前一个节点,firstsecond分别指向要交换的两个节点

  3. 判断是否还能交换:只有prev.nextprev.next.next都不为空时,后面才至少有两个节点,才能继续交换

三、思路详解

问题一:怎么返回新的头节点?

两两交换后,链表的头节点可能会改变

比如:

原链表:1 → 2 → 3 → 4 交换后:2 → 1 → 4 → 3

原来的头节点是 1,交换之后新的头节点变成了 2。如果直接拿原来的head返回,就会返回错误

最简单的解决办法是创建一个哑节点

ListNode dummy = new ListNode(0, head);

dummy.next指向原来的头节点。这样无论头节点怎么变化,dummy始终在链表最前面,最后返回dummy.next即可

dummy → 1 → 2 → 3 → 4 ↑ head 交换第一对后: dummy → 2 → 1 → 3 → 4 ↑ dummy.next(新的头节点) ↑ head(原来的头节点1已经不是头节点了) 返回 dummy.next,也就是 2

可以看到,如果仍然返回原来的head,返回的是节点 1,会丢失前面的节点 2;而返回dummy.next,就能拿到真正的新头节点

问题二:怎么判断是否还能继续交换?

两两交换的前提是:后面至少还有两个节点

对于奇数个节点的链表,最后一个节点无法交换:

1 → 2 → 3 → 4 → 5 交换后:2 → 1 → 4 → 3 → 5

最后的 5 没有配对节点,所以保持不变

在代码中,我们用prev指向当前要交换的一对节点的前一个节点。那么要判断后面是否还有两个节点,只需要看:

while (prev.next != null && prev.next.next != null)
  • prev.next != null:说明后面至少还有第一个节点
  • prev.next.next != null:说明后面至少还有第二个节点

只有两个条件都满足,才能进行交换。只要其中一个为 null,就说明剩下的节点构不成一对,循环结束

问题三:怎么交换两个相邻节点?

这是本题最关键、也最抽象的地方

假设当前链表片段如下:

prev → first → second → next

我们想把firstsecond交换,变成:

prev → second → first → next

其中:

first = prev.next; second = first.next;

也就是说,firstsecond这两个节点已经被变量记录下来了,所以交换过程中不用担心丢失它们。真正需要注意的是:交换后还要让后面的next链表保持不变

交换步骤

交换的三行代码是:

prev.next = second; first.next = second.next; second.next = first;

我们逐步看:

第一步:让 prev 指向 second

prev.next = second;
原来:prev → first → second → next 现在:prev → second → next first ────────↑(first暂时还指向second)
http://www.jsqmd.com/news/1090837/

相关文章:

  • 2026年最新AI写作辅助网站全攻略(含新手入门指南)
  • 市场分析化技术波特五力模型与SWOT分析应用
  • 微信聊天记录永久保存指南:本地备份与智能分析工具详解
  • React Fiber 调度器的优先级模型
  • PX4编译报错:子模块缺失的诊断与修复指南
  • 数据中心布线综合指南
  • 国产多功能高速数字化仪PXIe-7964R FPGA板卡(250M/16bit:4AI+2AO)兼容LabVIEW FPGA软件开发
  • d2s-editor:暗黑破坏神2存档编辑器的终极免费开源解决方案
  • OpenWrt IPv6配置实战:从零到一,打通家庭网络双栈访问
  • 【共创季稿事节】鸿蒙 ArkTS 布局进阶:@Reusable 可复用组件 —— 列表滚动性能优化的终极武器
  • 移动端接口参数逆向分析:从BSK参数抓包到Python算法还原
  • Python协程与异步编程实战
  • Python的__getattribute__审计
  • 默认修饰符和default修饰的方法
  • 2026年,市面上的TPU服装刻字膜生产厂家都有哪些新看点?
  • Celery Worker部署
  • 终极Chrome画中画扩展:5分钟解锁浏览器多任务处理
  • 论文提速的终极秘籍!智能AI写作辅助网站,逻辑优化超轻松
  • Python的__dict__属性与属性访问在元编程中的动态修改能力
  • 如何在Windows、macOS和Linux上免费体验Switch游戏:Ryujinx模拟器完整指南
  • Adobe GenP 3.0终极指南:如何免费解锁Adobe全系列创意软件
  • 工业品招投标效率低?实测AI智能体自动建档同步台账,告别手动搬砖
  • 57.从零学透 PLC 工业项目!传送带分拣 + 变频调速 + 时序逻辑全教程
  • 千万级客池圈选频发慢查询?深潜wecomapiSCRM标签引擎:位图高维索引、事件流异构同步与并发覆写阻断架构
  • 免费畅玩Switch游戏的终极方案:Ryujinx模拟器完整指南
  • [Python][MediaPipe] 跨平台与特定硬件环境WHL文件安装指南与疑难排解
  • BMS(电池管理系统)详细解析:从原理到架构
  • SVG学习笔记
  • 独立开发 AlphaLens 第 3 周:Vue3 + SpringBoot + DeepSeek 主动删掉了80%的功能
  • 选题毫无头绪?资深导师力荐这几个AI论文写作工具