原题链接🔗:两两交换链表中的节点
难度:中等⭐️⭐️
题目
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 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->4ListNode* 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