原题链接🔗:两两交换链表中的节点
难度:中等⭐️⭐️
题目
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
提示:
- 链表中节点的数目在范围 [0, 100] 内
- 0 <= Node.val <= 100
题解
迭代法【双指针迭代法】
- 题解:
"两两交换链表中的节点"是一个常见的链表问题,它主要考察对链表操作的理解和双指针技巧的应用。下面是解决这个问题的一般思路:
理解问题:首先明确题目要求,即给定一个链表,需要将链表中的节点两两交换,如果链表长度为奇数,最后一个节点保持不变。
虚拟头节点:为了简化操作,特别是处理原链表头节点的交换,可以创建一个虚拟头节点(dummy node),它的
next
指向原链表的头节点。这样,我们可以统一处理所有情况,包括链表只有一个节点或为空的情况。使用双指针:定义两个指针
current
和prev
。current
用于遍历链表,prev
用于指向当前current
节点的前一个节点。初始时,prev
指向虚拟头节点。遍历链表:遍历链表,每次循环处理一对节点。在每次循环中:
- 检查
current
和current->next
是否非空,确保有一对节点可以交换。- 交换
current
和current->next
的节点。可以通过改变指针的指向来实现节点的交换,而不需要移动节点的数据。交换节点:交换节点的步骤如下:
- 保存
current->next
的下一个节点,即second
。- 将
second
的next
指向current
。- 将
current->next
指向second
。- 更新
prev
的next
指向second
,即交换后的第二个节点。更新指针:交换完成后,更新
prev
为当前的current
,current
向前移动两位,即移动到下一对节点。处理特殊情况:如果链表长度为奇数,循环结束后,
current
将指向最后一个节点,此时不需要交换,直接结束循环。返回结果:最后,返回虚拟头节点的下一个节点,即交换后链表的新头节点。
释放资源:如果有必要,释放所有动态分配的节点,以避免内存泄漏。
这个算法的时间复杂度是O(n),其中n是链表的长度,因为我们只遍历了链表一次。空间复杂度是O(1),因为我们只使用了有限的额外空间。
- 复杂度: 时间复杂度O(n),其中n是节点数,空间复杂度O(1)。
- 代码过程:如demo所示。
- c++ demo:
#include <iostream>
// 定义链表节点结构体
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(nullptr) {}
};
// 两两交换链表中的节点
ListNode* swapPairs(ListNode* head) {
// 虚拟头节点,方便处理
ListNode* dummy = new ListNode(0);
dummy->next = head;
// 指向当前需要交换的节点
ListNode* current = dummy;
while (current->next && current->next->next) {
// 交换两个节点
ListNode* first = current->next;
ListNode* second = current->next->next;
first->next = second->next;
current->next = second;
second->next = first;
// 移动到下一对节点
current = first;
}
// 返回新链表的头节点
ListNode* newHead = dummy->next;
delete dummy; // 释放虚拟头节点
return newHead;
}
// 打印链表的函数,用于验证结果
void printList(ListNode* head) {
while (head) {
std::cout << head->val << " ";
head = head->next;
}
std::cout << std::endl;
}
// 测试代码
int main() {
// 创建示例链表: 1->2->3->4
ListNode* head = new ListNode(1);
head->next = new ListNode(2);
head->next->next = new ListNode(3);
head->next->next->next = new ListNode(4);
std::cout << "Original List: ";
printList(head);
// 调用函数交换节点
ListNode* newHead = swapPairs(head);
std::cout << "Swapped List: ";
printList(newHead);
// 释放链表内存
while (newHead) {
ListNode* temp = newHead;
newHead = newHead->next;
delete temp;
}
return 0;
}
- 输出结果:
Original List: 1 2 3 4
Swapped List: 2 1 4 3