Medium
题目描述
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改链表节点值的情况下完成本题(即,只能进行节点交换)。
示例 1:
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
示例 4:
输入:head = [1,2,3]
输出:[2,1,3]
提示:
- 链表中节点的数目在范围 [0, 100] 内
- 0 <= Node.val <= 100
解题思路
这道题要求两两交换链表中的相邻节点。我们可以用迭代或递归的方式来解决。
方法一:迭代法(推荐)
使用虚拟头节点来简化边界情况的处理。我们维护三个指针:
prev:指向当前需要交换的两个节点的前一个节点first:指向当前需要交换的第一个节点second:指向当前需要交换的第二个节点
交换过程:
- 将
prev.next指向second - 将
first.next指向second.next - 将
second.next指向first - 更新
prev指向first,准备下一轮交换
方法二:递归法
递归思路更加直观:
- 先递归处理从第三个节点开始的子链表
- 交换当前的前两个节点
- 返回交换后的头节点
迭代法的空间复杂度更优,是首选解法。
代码实现
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode dummy(0);
dummy.next = head;
ListNode* prev = &dummy;
while (prev->next && prev->next->next) {
ListNode* first = prev->next;
ListNode* second = prev->next->next;
// 交换节点
prev->next = second;
first->next = second->next;
second->next = first;
// 移动到下一对节点
prev = first;
}
return dummy.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:
first = prev.next
second = prev.next.next
# 交换节点
prev.next = second
first.next = second.next
second.next = first
# 移动到下一对节点
prev = first
return dummy.next
public 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;
// 交换节点
prev.next = second;
first.next = second.next;
second.next = first;
// 移动到下一对节点
prev = first;
}
return dummy.next;
}
}
var swapPairs = function(head) {
let dummy = new ListNode(0);
dummy.next = head;
let prev = dummy;
while (prev.next && prev.next.next) {
let first = prev.next;
let second = prev.next.next;
// 交换节点
prev.next = second;
first.next = second.next;
second.next = first;
// 移动到下一对节点
prev = first;
}
return dummy.next;
};
复杂度分析
| 复杂度类型 | 时间复杂度 | 空间复杂度 |
|---|---|---|
| 迭代法 | O(n) | O(1) |
| 递归法 | O(n) | O(n) |
其中 n 是链表的长度。迭代法只使用常数额外空间,而递归法需要 O(n) 的递归栈空间。
相关题目
. Reverse Nodes in k-Group (Hard)
. Swapping Nodes in a Linked List (Medium)