LeetCode hot 100—两两交换链表中的节点
题目
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例
示例 1:
输入:head = [1,2,3,4] 输出:[2,1,4,3]示例 2:
输入:head = [] 输出:[]示例 3:
输入:head = [1] 输出:[1]
分析
迭代法
迭代方法通过循环遍历链表,依次交换相邻的两个节点。我们需要维护几个指针来完成节点的交换操作。
创建虚拟头节点:创建一个虚拟头节点 dummy
,并将其 next
指针指向原链表的头节点 head
,同时使用 prev
指针指向 dummy
,方便后续操作。
循环交换节点:只要 head
和 head->next
不为空,就进行交换操作。
保存当前相邻的两个节点 first
和 second
。
交换这两个节点:将 prev->next
指向 second
,first->next
指向 second->next
,second->next
指向 first
。
更新指针:交换完成后,更新 prev
指针为 first
,head
指针为 first->next
,继续下一轮交换。
返回结果:最终返回 dummy.next
,即交换后链表的头节点。
时间复杂度:O(),
是链表的长度
空间复杂度:O(1)
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode dummy(0);
dummy.next = head;
ListNode* prev = &dummy;
while (head && head->next) {
ListNode* first = head;
ListNode* second = head->next;
// 交换节点
prev->next = second;
first->next = second->next;
second->next = first;
// 更新指针
prev = first;
head = first->next;
}
return dummy.next;
}
};
递归法
递归方法通过递归地处理链表的剩余部分,然后再交换当前相邻的两个节点。
递归终止条件:如果 head
为空或者 head->next
为空,说明没有节点或者只有一个节点,直接返回 head
。
保存当前相邻节点:保存当前相邻的两个节点 first
和 second
。
递归处理剩余部分:递归调用 swapPairs
函数处理 second->next
之后的链表,将结果赋值给 first->next
。
交换节点:将 second->next
指向 first
。
返回结果:返回 second
,因为交换后 second
成为了新的头节点。
时间复杂度:O(),
是链表的长度
空间复杂度:O()
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if (!head || !head->next) {
return head;
}
ListNode* first = head;
ListNode* second = head->next;
// 递归处理剩余部分
first->next = swapPairs(second->next);
second->next = first;
return second;
}
};