news 2026/9/10 18:37:44

链表专题(三):双人舞的艺术——「两两交换链表中的节点」

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
链表专题(三):双人舞的艺术——「两两交换链表中的节点」

场景想象:链表里的节点在排队:1 -> 2 -> 3 -> 4。 现在要求:每两个节点为一组,互换位置

  • 12交换,变成2 -> 1

  • 34交换,变成4 -> 3

  • 最后连起来:2 -> 1 -> 4 -> 3

核心痛点:很多同学会直接把节点的值互换(val互换),虽然能过 LeetCode,但这不是面试官想要的。面试官考的是修改指针指向。 要交换12,你需要操作三个步骤,而且必须小心翼翼,一旦断链就全完了。

力扣 24. 两两交换链表中的节点

https://leetcode.cn/problems/swap-nodes-in-pairs/

题目分析:

  • 输入:链表头节点head

  • 目标:两两交换相邻节点。

  • 输出:交换后的链表头节点。

核心思维:虚拟头结点 + 三步走

既然头结点1也要被换到后面去,那头结点肯定会变。口诀:头结点会变,虚拟头结点 (Dummy Head)必不可少!

我们需要一个指针temp指向要交换的两个节点前面的那个位置(初始指向 dummy)。 假设当前是temp -> 1 -> 2 -> 3。我们要交换12。 设node1 = 1,node2 = 2

交换三部曲(画图奇效):

  1. temp.next = node2(步骤一:前面的线连到 2)

    • 状态:temp -> 2,1 -> 2 -> 3

  2. node2.next = node1(步骤二:2 回头连 1)

    • 状态:temp -> 2 -> 1,1 -> 2(这里形成了个小环),1 -> 3(别忘了1还指着3)

  3. node1.next = node3(步骤三:1 连向后面的 3)

    • 状态:temp -> 2 -> 1 -> 3完美!

最后,temp前进到node1的位置(也就是交换后的第二个节点),准备处理下一组34

代码实现 (JavaScript)

JavaScript

/** * Definition for singly-linked list. * function ListNode(val, next) { * this.val = (val===undefined ? 0 : val) * this.next = (next===undefined ? null : next) * } */ /** * @param {ListNode} head * @return {ListNode} */ var swapPairs = function(head) { // 1. 虚拟头结点:凡是头结点会动的题,无脑上 dummy let dummy = new ListNode(0, head); // temp 是当前操作组的“前驱节点” let temp = dummy; // 循环条件:必须要后面至少有两个节点,才能交换 // temp.next 是第一个,temp.next.next 是第二个 while (temp.next !== null && temp.next.next !== null) { // 2. 定义两个要交换的节点 let node1 = temp.next; // 第一个节点 (1) let node2 = temp.next.next; // 第二个节点 (2) // 3. 开启交换三部曲 // 步骤一:前驱指后一个 (dummy -> 2) temp.next = node2; // 步骤二:后一个指前一个 (2 -> 1) node2.next = node1; // 步骤三:前一个指下下个 (1 -> 3) // 注意:这里用 node1.next 指向 node2 原来的 next // 但此时 node2.next 已经被改了,所以要拿 temp.next.next 吗? // 不对,应该在交换前把 node3 保存下来,或者利用 node1.next 还没改的时候 // 其实最简单的是:node1.next = node2.next (这里 node2.next 已经被改成 node1 了,会死循环) // --- 修正逻辑 --- // 我们需要先保存 node3 (下一组的开头) // 或者按顺序操作,不要把自己绕晕 // 让我们重来最清晰的写法: // 先保存下一轮的起点 (3) let nextStart = node2.next; temp.next = node2; // dummy -> 2 node2.next = node1; // 2 -> 1 node1.next = nextStart; // 1 -> 3 // 4. 指针前进 // 此时链表是 dummy -> 2 -> 1 -> 3 -> 4 // 下一轮我们要站在 1 的位置,去处理 3 和 4 temp = node1; } return dummy.next; };

深度模拟

假设dummy -> 1 -> 2 -> 3 -> 4

  1. 初始temp = dummy

    • 检查:后面有 1 和 2。可以换。

    • node1 = 1,node2 = 2,nextStart = 3

    • 连线:dummy -> 22 -> 11 -> 3

    • 链表变:dummy -> 2 -> 1 -> 3 -> 4

    • 移动temp跳到1

  2. 第二轮temp = 1

    • 检查:后面有 3 和 4。可以换。

    • node1 = 3,node2 = 4,nextStart = null

    • 连线:1 -> 44 -> 33 -> null

    • 链表变:dummy -> 2 -> 1 -> 4 -> 3 -> null

    • 移动temp跳到3

  3. 结束temp后面没节点了,循环结束。

总结

这道题是“多指针操作”的典型训练。

  • 不要试图要在脑子里模拟三根线的变化,一定会晕。

  • 一定要画图,把步骤 1、2、3 标在纸上,代码自然就写出来了。

  • 只要掌握了这题,后面的 K 个一组翻转(LC 25)其实就是把“两两”变成了“K个”,逻辑是一模一样的。


下一题预告:删除链表的倒数第 N 个结点

练完了细致的指针操作,下一题LC 19. 删除链表的倒数第 N 个结点要考一点**“小聪明”**了。

  • 题目:只扫描一遍链表,怎么找到倒数第 N 个节点?

  • 技巧:快慢指针。让快指针先跑 N 步,然后两个指针一起跑。当快指针到头时,慢指针正好停在你想要的地方。

这是一种非常经典的**“尺子思维”**,准备好去测量链表的长度了吗?

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

从零构建C#可靠传输协议,解决粘包、断线重连等9大难题

第一章:C#网络通信协议设计概述 在构建分布式系统和跨平台应用时,网络通信协议的设计是核心环节之一。C# 作为 .NET 平台的主要语言,提供了丰富的类库支持,如 System.Net.Sockets 和 System.IO.Pipelines,使得开发者…

作者头像 李华
网站建设 2026/8/30 16:15:59

uniapp+vuessm家庭食谱菜谱食材网上商城系统小程序ko137-vue

目录系统概述核心功能技术亮点应用场景关于博主开发技术介绍核心代码参考示例1.建立用户稀疏矩阵,用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式&#x…

作者头像 李华
网站建设 2026/9/8 3:04:52

uniapp+vue微信小程序javassm图书馆座位签到离开管理系统

目录摘要关于博主开发技术介绍核心代码参考示例1.建立用户稀疏矩阵,用于用户相似度计算【相似度矩阵】2.计算目标用户与其他用户的相似度系统测试总结源码文档获取/同行可拿货,招校园代理 :文章底部获取博主联系方式!摘要 该系统基于UniAppV…

作者头像 李华
网站建设 2026/9/3 0:59:05

Three.js能否集成HeyGem输出?探索数字人视频的3D展示方式

Three.js能否集成HeyGem输出?探索数字人视频的3D展示方式 在虚拟主播频繁出没于直播间、AI客服全天候在线应答的今天,数字人早已不再是科幻电影里的专属角色。它们正以越来越自然的姿态融入我们的数字生活——但大多数时候,这些“人”还只是被…

作者头像 李华
网站建设 2026/9/8 18:17:34

【C#开发效率飞跃秘诀】:你不可错过的Lambda高级用法

第一章:Lambda表达式的核心概念与演进Lambda表达式是一种匿名函数,能够以简洁的语法将行为作为参数传递,广泛应用于函数式编程范式中。它最早出现在Lisp语言中,如今已成为Java、C#、Python、JavaScript等多种主流语言的重要特性。…

作者头像 李华
网站建设 2026/8/21 7:00:54

C#系统部署实战精要(从开发到运维的9个关键细节)

第一章:C#企业系统部署概述在现代企业级应用开发中,C#凭借其强大的生态系统和与Windows平台的深度集成,广泛应用于后端服务、桌面应用及Web系统的构建。部署C#企业系统不仅仅是将编译后的程序集发布到目标服务器,更涉及环境配置、…

作者头像 李华