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

输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
提示:
- 链表中节点的数目在范围
[0, 100]内 0 <= Node.val <= 100
思路解析
- 虚拟头节点 :创建
dummy节点并让它指向原链表头,这样可以统一处理头节点和后续节点的交换逻辑,避免头节点特殊处理。 - 迭代交换 :用
prev指针跟踪当前交换组的前一个节点,每次循环处理prev.next和prev.next.next两个节点:- 先保存两个节点的引用
node1和node2。 - 调整指针完成交换:让
prev指向node2,node1指向node2的下一个节点,node2指向node1。 - 移动
prev到node1,准备处理下一组节点。
- 先保存两个节点的引用
- 终止条件 :当
prev.next或prev.next.next为空时,说明没有更多可交换的节点,结束循环。 - 返回结果 :最终返回
dummy.next,即交换后的新链表头。
示例验证
对于输入 head = [1,2,3,4]:
- 初始
dummy -> 1 -> 2 -> 3 -> 4 - 第一次交换后:
dummy -> 2 -> 1 -> 3 -> 4,prev移动到1 - 第二次交换后:
dummy -> 2 -> 1 -> 4 -> 3,prev移动到3 - 循环结束,返回
dummy.next即2 -> 1 -> 4 -> 3,与示例输出一致。
Python代码
python
from typing import Optional, List
# Definition for singly-linked list.
class ListNode:
def __init__(self, val=0, next=None):
self.val = val
self.next = next
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
# 虚拟头节点,统一处理头节点交换(避免头节点特殊逻辑)
dummy = ListNode(0)
dummy.next = head
prev = dummy # 指向当前交换组的前一个节点
# 循环条件:至少有两个节点可交换
while prev.next and prev.next.next:
# 取出当前要交换的两个节点
node1 = prev.next # 第一个待交换节点
node2 = prev.next.next # 第二个待交换节点
# 核心:调整指针完成两两交换
prev.next = node2 # 前一个节点指向第二个节点(交换后第一个节点)
node1.next = node2.next # 第一个节点指向第二个节点的下一个节点
node2.next = node1 # 第二个节点指向第一个节点
# 移动指针到下一组的前一个节点(即当前交换后的第二个节点)
prev = node1
# 返回交换后的链表头(虚拟头节点的下一个节点)
return dummy.next
# 辅助函数1:从列表创建链表(方便测试)
def create_linked_list(nums: List[int]) -> Optional[ListNode]:
if not nums:
return None
head = ListNode(nums[0])
current = head
for num in nums[1:]:
current.next = ListNode(num)
current = current.next
return head
# 辅助函数2:打印链表(直观查看结果)
def print_linked_list(head: Optional[ListNode]) -> None:
current = head
result = []
while current:
result.append(str(current.val))
current = current.next
print(" -> ".join(result) if result else "空链表")
# 测试用例(覆盖常见场景)
if __name__ == "__main__":
solution = Solution()
# 测试用例1:偶数个节点 [1,2,3,4] → 预期 [2,1,4,3]
test1 = create_linked_list([1, 2, 3, 4])
print("测试用例1 原链表:", end="")
print_linked_list(test1)
res1 = solution.swapPairs(test1)
print("测试用例1 交换后:", end="")
print_linked_list(res1)
# 测试用例2:奇数个节点 [1,2,3] → 预期 [2,1,3]
test2 = create_linked_list([1, 2, 3])
print("\n测试用例2 原链表:", end="")
print_linked_list(test2)
res2 = solution.swapPairs(test2)
print("测试用例2 交换后:", end="")
print_linked_list(res2)
# 测试用例3:空链表 → 预期 空链表
test3 = create_linked_list([])
print("\n测试用例3 原链表:", end="")
print_linked_list(test3)
res3 = solution.swapPairs(test3)
print("测试用例3 交换后:", end="")
print_linked_list(res3)
# 测试用例4:单个节点 [1] → 预期 [1]
test4 = create_linked_list([1])
print("\n测试用例4 原链表:", end="")
print_linked_list(test4)
res4 = solution.swapPairs(test4)
print("测试用例4 交换后:", end="")
print_linked_list(res4)
LeetCode提交代码
python
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def swapPairs(self, head: Optional[ListNode]) -> Optional[ListNode]:
# 虚拟头节点,统一处理头节点交换
dummy = ListNode(0)
dummy.next = head
prev = dummy
while prev.next and prev.next.next:
# 取出当前要交换的两个节点
node1 = prev.next
node2 = prev.next.next
# 交换节点
prev.next = node2
node1.next = node2.next
node2.next = node1
# 移动指针到下一组的前一个节点
prev = node1
return dummy.next
程序运行结果展示
测试用例1 原链表:1 -> 2 -> 3 -> 4
测试用例1 交换后:2 -> 1 -> 4 -> 3
测试用例2 原链表:1 -> 2 -> 3
测试用例2 交换后:2 -> 1 -> 3
测试用例3 原链表:空链表
测试用例3 交换后:空链表
测试用例4 原链表:1
测试用例4 交换后:1
总结
本文介绍了如何通过迭代方法实现链表相邻节点的两两交换。通过创建虚拟头节点(dummy)统一处理头节点交换,使用prev指针跟踪交换组前驱节点,每次循环交换prev.next和prev.next.next两个节点。算法时间复杂度O(n),空间复杂度O(1)。代码实现包含链表创建、打印等辅助函数,并测试了偶数节点、奇数节点、空链表和单节点等典型情况,验证了算法的正确性。关键步骤包括保存节点引用、调整指针顺序完成交换,以及移动prev指针准备下一轮交换。