hot 100 第三十题 30. 两两交换链表中的节点

题目

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

示例 1:

复制代码
输入:head = [1,2,3,4]
输出:[2,1,4,3]

示例 2:

复制代码
输入:head = []
输出:[]

示例 3:

复制代码
输入:head = [1]
输出:[1]

核心思路

迭代法:每次处理两个节点,改变它们的next指针实现交换。

复制代码
原链表: 1 → 2 → 3 → 4

交换1和2:
2 → 1 → 3 → 4

交换3和4:
2 → 1 → 4 → 3

结果: 2 → 1 → 4 → 3

题解

复制代码
class Solution {
    public ListNode swapPairs(ListNode head) {
        // 使用哑节点简化处理
        ListNode dummy = new ListNode(0);
        dummy.next = head;
        ListNode prev = dummy;
        
        // 至少需要两个节点才能交换
        while (prev.next != null && prev.next.next != null) {
            // 定义要交换的两个节点
            ListNode first = prev.next;
            ListNode second = prev.next.next;
            
            // 交换节点(三步)
            first.next = second.next;   // 1指向3
            second.next = first;        // 2指向1
            prev.next = second;         // prev指向2
            
            // 移动prev到下一对的前一个节点
            prev = first;
        }
        
        return dummy.next;
    }
}
```

### 详细演示
```
原链表: 1 → 2 → 3 → 4

步骤1: 创建哑节点
------------------
dummy → 1 → 2 → 3 → 4
prev↑

步骤2: 第一次交换(1和2)
------------------
定义节点:
first = 1
second = 2

交换前:
dummy → 1 → 2 → 3 → 4
prev↑  ↑   ↑
     first second

执行交换三步:

① first.next = second.next
   1 → 3

dummy → 1 → 2 → 3 → 4
        ↓       ↑
        └───────┘

② second.next = first
   2 → 1

dummy → 1 ← 2   3 → 4
        ↓   ↑
        └───┘

③ prev.next = second
   dummy → 2

dummy → 2 → 1 → 3 → 4
        ↑   ↓   ↑
        └───┴───┘

交换完成:
dummy → 2 → 1 → 3 → 4

移动prev:
prev = first (现在first是节点1)

dummy → 2 → 1 → 3 → 4
            prev↑

步骤3: 第二次交换(3和4)
------------------
定义节点:
first = 3
second = 4

交换前:
dummy → 2 → 1 → 3 → 4
            prev↑ ↑   ↑
                 first second

执行交换:
① first.next = second.next
   3 → null

② second.next = first
   4 → 3

③ prev.next = second
   1 → 4

结果:
dummy → 2 → 1 → 4 → 3 → null

移动prev:
prev = first (节点3)

步骤4: 检查循环条件
------------------
prev.next = 3
prev.next.next = null

条件不满足,循环结束

返回 dummy.next
最终: 2 → 1 → 4 → 3
```

## 交换的三步详解

这是最关键的部分,顺序不能错:
```
交换前:
prev → first → second → next
  ↑      ↑       ↑       ↑
dummy    1       2       3

目标:
prev → second → first → next
  ↑      ↑       ↑       ↑
dummy    2       1       3

三步:
------------------
步骤1: first.next = second.next
让1指向3(跳过2)

prev → first   second → next
        ↓   ╲    ↑       ↑
        └────╲───┘       │
              ╲__________│

步骤2: second.next = first
让2指向1

prev → first ← second → next
        ↓              ↗
        └──────────────┘

步骤3: prev.next = second
让prev指向2

prev ──→ second → first → next
           ↑       ↑       ↑
           2       1       3

完成!
```

## 图解交换过程
```
原始状态:
dummy → 1 → 2 → 3 → 4
        ↑   ↑
      first second

目标状态:
dummy → 2 → 1 → 3 → 4
        ↑   ↑
     second first

改变指针方向:
1. 1.next = 3     (1跳过2)
2. 2.next = 1     (2指回1)
3. dummy.next = 2 (dummy指向2)

本质

两两交换链表节点体现了:

  1. 指针作 --- 改变next指针实现节点重排
  2. 固定的交换步骤 --- 三步法完成交换
  3. 哑节点技巧 --- 统一处理头节点

关键是理解交换的三步顺序

  1. first.next = second.next(保存后续)
  2. second.next = first(交换)
  3. 上一页下一页 = second(连接)
相关推荐
得一录1 小时前
Python 算法高级篇:布谷鸟哈希算法与分布式哈希表
python·算法·aigc·哈希算法
啊吧啊吧abab1 小时前
二分查找与二分答案
c++·算法·二分
AC赳赳老秦1 小时前
2026 智能制造趋势:DeepSeek 助力“黑灯”工厂运营,实现生产流程自动化
网络·数据结构·算法·安全·web安全·prometheus·deepseek
流云鹤1 小时前
2026牛客寒假算法基础集训营6(K H G B A)
算法
寻寻觅觅☆2 小时前
东华OJ-基础题-131-8皇后·改(C++)
c++·算法·深度优先
踩坑记录2 小时前
leetcode hot100 207. 课程表 检测有向图中是否存在环 medium Kahn 算法 入度表 BFS 图论
leetcode·宽度优先
程序员徐师兄2 小时前
基于 Python 深度学习的电影评论情感分析算法
python·深度学习·算法·电影情感分析算法·评论情感分析
ShineWinsu2 小时前
对于C++中list的详细介绍
开发语言·数据结构·c++·算法·面试·stl·list
_OP_CHEN2 小时前
【算法提高篇】(三)线段树之维护更多的信息:从基础到进阶的灵活运用
算法·蓝桥杯·线段树·c/c++·区间查询·acm/icpc·信息维护