深入解析“两两交换链表中的节点”算法
在链表算法的世界里,“两两交换链表中的节点”是一道经典且颇具技巧性的题目。它要求我们在不改变节点内部值的前提下,仅通过交换节点来实现链表结构的调整。这不仅考验对链表结构的熟悉程度,还需要巧妙运用指针操作来完成任务。下面,我们就一起深入探究这一算法。
一、问题描述
给定一个链表,需要将链表中相邻的节点两两进行交换,并返回交换后链表的头节点。并且明确规定,只能进行节点交换操作,不能修改节点内部的值。例如:
- 当输入链表
head = [1,2,3,4]
时,经过交换后,输出链表为[2,1,4,3]
。 - 若输入链表
head = []
,则输出链表也为[]
。 - 当输入链表
head = [1]
时,由于没有相邻节点可交换,所以输出链表仍为[1]
。同时题目提示链表中节点的数目在范围[0, 100]
内,节点值范围是0 <= Node.val <= 100
。
二、算法思路
迭代法思路
- 首先创建一个虚拟头节点
dummy
,它的作用是方便我们统一处理链表的头节点交换情况,避免单独对链表头进行特殊判断。将dummy
的next
指向原链表的头节点head
。 - 定义一个指针
prev
指向虚拟头节点dummy
,然后开始遍历链表。每次处理相邻的两个节点,设为first
和second
。 - 交换
first
和second
节点的位置:- 先将
first
的next
指向second
的next
。 - 再将
second
的next
指向first
。 - 最后将
prev
的next
指向second
。
- 先将
- 完成一次交换后,将
prev
移动到first
节点的位置,继续向后遍历链表,重复上述交换操作,直到遍历完整个链表。
递归法思路
- 递归的终止条件是链表为空或者链表中只剩下一个节点,此时直接返回当前链表头节点。
- 对于有两个及以上节点的链表,设当前的两个节点为
first
和second
。 - 先递归处理
second
节点之后的链表部分,得到交换后的子链表。 - 然后进行节点交换:将
second
的next
指向first
,first
的next
指向递归返回的子链表。 - 最终返回
second
节点,它成为了交换后的新头节点。
三、示例代码(Java)
迭代法代码
class ListNode {