
24. 两两交换链表中的节点
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:

输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
提示:
- 链表中节点的数目在范围
[0, 100]
内 0 <= Node.val <= 100
解题思路:递归
这道题其实是 206. 反转链表 的变形,我们只需要对链表中的两两节点进行逆序,那说明其实每两个节点其实操作都是一致的,于是我们就可以采用递归的方式来解决问题,分三步走:
- 函数头的设计:
- 因为这道题要返回的就是处理完之后的新头节点,那么返回的肯定是一个
ListNode*
类型,并且我们需要进行节点的交换操作,不过我们可以通过node
与node->next
进行操作,所以只需要一个变量即可!
- 因为这道题要返回的就是处理完之后的新头节点,那么返回的肯定是一个
- 函数体的内容:
- 首先和 206. 反转链表 这道题一样,为了方便在处理完
node
以及node->next
的交换之后,node->next->next
丢失的情况,我们就可以采用 后序遍历,也就是先完成后面两两组合,最后再处理当前的两个节点! - 然后就是交换两个节点,在交换之前,我们得先用将
node->next
保存起来,因为最后我们要返回两两交换之后的新节点,所以在交换操作之前就得先将其用变量保存起来,方便后续的返回! - 最后无非就是返回上面保存的
node->next
了!
- 首先和 206. 反转链表 这道题一样,为了方便在处理完
- 递归函数出口:
- 终止条件其实很简单,因为只有两个节点的时候才需要操作,所以当只有一个节点或者当前节点为空了,那么直接返回空即可!
/**
* 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* next_level = swapPairs(head->next->next);
// 交换两个节点,然后链接新的尾节点
ListNode* ret = head->next;
ret->next = head;
head->next = next_level;
// 最后返回两两逆序后的新头节点
return ret;
}
};