代码随想录 第二章 链表 24. 两两交换链表中的节点
题目:力扣链接
- 题目描述:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
一、思想
通过虚拟头节点简化边界条件处理,使用指针两两交换相邻节点。具体步骤是:
- 保存当前对的首节点和下一对节点的起始位置。
- 交换当前对的两个节点,并更新指针指向。
- 移动指针到下一对节点的前一个位置,重复上述步骤,直到链表遍历完毕。
二、代码
/**
* 定义解决方案类
*/
class Solution
{
public:
/**
* 交换链表中的每两个相邻节点
* @param head 链表的头节点
* @return 交换后的链表头节点
*/
ListNode *swapPairs(ListNode *head)
{
// 创建虚拟头节点,简化边界条件处理
ListNode *dummy = new ListNode(0, head);
// cur指针用于遍历链表
ListNode *cur = dummy;
// 定义两个临时指针用于节点交换
ListNode *nextPair, *thisPair;
// 当存在至少两个节点时进行交换
while (cur->next && cur->next->next) {
// 保存下一对节点的起始位置
nextPair = cur->next->next->next;
// 保存当前对的首节点
thisPair = cur->next;
// 交换节点:
// 1. 将cur的next指向第二个节点
cur->next = cur->next->next;
// 2. 将第二个节点的next指向第一个节点
cur->next->next = thisPair;
// 3. 将第一个节点的next指向下一对节点
thisPair->next = nextPair;
// 移动cur指针到下一对节点的前一个位置
cur = cur->next->next;
}
// 返回交换后的链表头节点
return dummy->next;
}
};
三、代码解析
1. 算法工作原理分解
-
初始化虚拟头节点:
- 创建虚拟头节点
dummy,并将其next 指向链表头节点,简化边界条件处理。 - 使用
cur 指针遍历链表,初始指向dummy。
- 创建虚拟头节点
-
交换相邻节点:
- 保存当前对的首节点
thisPair 和下一对节点的起始位置nextPair。 - 将
cur->next 指向第二个节点,完成第一个交换。 - 将第二个节点的
next 指向第一个节点,完成第二个交换。 - 将第一个节点的
next 指向nextPair,完成当前对的交换。
- 保存当前对的首节点
-
移动指针:
- 将
cur 指针移动到下一对节点的前一个位置,继续处理下一对节点。
- 将
-
返回结果:
- 返回
dummy->next,即交换后的链表头节点。
- 返回
2. 关键点说明
- 虚拟头节点:简化边界条件处理,避免单独处理头节点交换。
- 指针保存:使用
thisPair 和nextPair 保存节点信息,防止丢失链表连接。 - 交换逻辑:通过三步操作完成相邻节点的交换,确保链表连接正确。
四、复杂度分析
-
时间复杂度:O(n)
- 需要遍历整个链表一次,时间复杂度为
O(n),其中n 是链表的长度。 - 每个节点只需处理一次,因此时间复杂度为线性。
- 需要遍历整个链表一次,时间复杂度为
-
空间复杂度:O(1)
- 只使用了常数级别的额外空间(虚拟头节点和指针
cur、thisPair、nextPair)。 - 无论链表长度如何,额外空间都是固定的。
- 只使用了常数级别的额外空间(虚拟头节点和指针

369

被折叠的 条评论
为什么被折叠?



