leetcode 24. 两两交换链表中的节点
题目描述:
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
解题分析:
方法一:迭代法
使用虚拟头节点 dummy,令 dummy->next = head。cur
表示当前节点,每次需要交换 cur 后面的两个节点。即交换之前: cur -> a -> b,交换之后: cur -> b -> a,完成之后,将 cur更新为 a ,对链表中的其他节点进行两两交换。
直到 cur 后面没有节点或者只有一个节点时,交换就终止了。
时间复杂度:O(n)。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
auto dummy = new ListNode(0); //设置虚拟头节点
dummy->next = head; //虚拟头节点指向head
ListNode* cur = dummy;
while (cur->next && cur->next->next) {
ListNode* a = cur->next;
ListNode* b = a->next;
cur->next = b;
a->next = b->next;
b->next = a;
cur = a; //cur移动,准备下一轮交换
}
return dummy->next;
}
};
方法二:递归法
同迭代法类似,当链表中没有节点或只有一个节点时,不能进行交换了,就终止了。
否则,在两两交换之后,原链表的第二个节点变成新链表的头节点,原链表的头节点变成新链表的第二个节点。剩余的节点的两两交换可以递归地实现。
时间复杂度: O(n)。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if (head == nullptr || head->next == nullptr ) {
return head;
}
ListNode* res = head->next;
head->next = swapPairs(res->next);
res->next = head;
return res;
}
};