LeetCode 热题 100 24. 两两交换链表中的节点
LeetCode 热题 100 | 24. 两两交换链表中的节点
大家好,今天我们来解决一道经典的链表问题——两两交换链表中的节点。这道题在 LeetCode 上被标记为中等难度,要求两两交换链表中的相邻节点,并返回交换后链表的头节点。
问题描述
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
提示:
- 链表中节点的数目在范围
[0, 100]
内 0 <= Node.val <= 100
解题思路
核心思想
-
虚拟头结点:
- 使用一个虚拟头结点
dummy
,其next
指向链表的头结点。这可以简化对头结点的处理。
- 使用一个虚拟头结点
-
两两交换:
- 使用一个指针
prev
,初始时指向虚拟头结点。 - 每次交换
prev.next
和prev.next.next
指向的两个节点。 - 更新指针,继续处理下一对节点。
- 使用一个指针
-
特殊情况:
- 如果链表为空或只有一个节点,直接返回原链表。
Python代码实现
class Solution:def swapPairs(self, head: ListNode) -> ListNode:# 创建一个虚拟头结点dummy = ListNode(0)dummy.next = headprev = dummywhile prev.next and prev.next.next:# 定义需要交换的两个节点first = prev.nextsecond = prev.next.next# 交换节点prev.next = secondfirst.next = second.nextsecond.next = first# 移动 prev 指针prev = firstreturn dummy.next
代码解析
-
虚拟头结点:
- 创建一个虚拟头结点
dummy
,并将其next
指向链表的头结点。这可以简化对头结点的处理。
- 创建一个虚拟头结点
-
初始化指针:
- 初始化指针
prev
,指向虚拟头结点。
- 初始化指针
-
两两交换:
- 使用
while
循环,条件是prev.next
和prev.next.next
都不为None
。 - 定义需要交换的两个节点
first
和second
。 - 交换节点:
prev.next
指向second
。first.next
指向second.next
。second.next
指向first
。
- 更新
prev
指针,继续处理下一对节点。
- 使用
-
返回结果:
- 返回
dummy.next
,即交换后的链表头结点。
- 返回
复杂度分析
- 时间复杂度:O(n),其中
n
是链表的长度。每个节点只被访问一次。 - 空间复杂度:O(1),只使用了常数级别的额外空间。
示例运行
示例 1
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2
输入:head = []
输出:[]
示例 3
输入:head = [1]
输出:[1]
总结
通过使用虚拟头结点和两两交换的方法,我们可以高效地完成链表中相邻节点的交换。这种方法在 O(n) 时间复杂度内完成,并且只使用了 O(1) 的额外空间。希望这篇题解对大家有所帮助,如果有任何问题,欢迎在评论区留言讨论!
关注我,获取更多算法题解和编程技巧!