目录链接:https://www.jianshu.com/p/9c0ada9e0ede
两两交换其中相邻的节点
LeetCode 24. 两两交换链表中的节点(Swap Nodes in Pairs)
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.
切题
一、Clarification
目标明确两两交换链表中的节点,无特别需要注意的边界但需常规关注下空链表和只有一个元素的链表
二、Possible solutions
1、迭代
在边界内同时取出2个节点并交换,然后向下移动2位
使用哨兵简化处理,空链表,一个元素的链表
2、递归
递归终止条件 head 和 head.next 为None
每层递归交换当前两节点,并返回 交换后两个节点中的前一个节点
Python3 实现
迭代实现
两两交换其中相邻的节点(Swap Nodes in Pairs) Py3 迭代实现
#@author:leacoder
#@des: 循环实现 多元赋值
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
pre = ListNode(None) # 哨兵
retult,pre.next =pre, head
while pre.next and pre.next.next:
a = pre.next
b = pre.next.next # 记录 要交换的两节点
pre.next,b.next,a.next,= b,a,b.next # 2个节点交换,注意哨兵的next改变了
pre = a # 向下移动2位
return retult.next
递归实现
#@author:leacoder
#@des: 递归实现 多元赋值
class Solution:
def swapPairs(self, head: ListNode) -> ListNode:
if not head or not head.next:
return head
resultmp = self.swapPairs(head.next.next) # 下移两位 返回 值为两两交换后 两个节点中的前一个节点
# 交换 当前两节点
A, B = head, head.next # 当前两节点
A.next, B.next = resultmp,A # 交换
return B # 返回 两两交换后 两个节点中的前一个节点
C++实现
1、迭代实现 C++
两两交换其中相邻的节点(Swap Nodes in Pairs) C++ 迭代实现
* @author:leacoder
* @des: 迭代实现 两两交换链表中的节点
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
/*在头节点前 新建一节点,其next指向head。好处 将[]\[1]这种特殊情况能够统一处理*/
ListNode *virtualnode = new ListNode(0);
virtualnode->next = head;
ListNode *node = virtualnode;//存储新的开始节点
while(head&&head->next){
ListNode *tmp = head->next;//不变的
head->next = tmp->next;
tmp->next = head;//交换
node->next = tmp;
node = head;
head = node->next;//下移
}
return virtualnode->next;
}
};
2、递归实现 C++
两两交换其中相邻的节点(Swap Nodes in Pairs) C++ 递归实现
/**
* @author:leacoder
* @des: 递归实现 两两交换链表中的节点
*/
class Solution {
public:
//每两个节点为一组 反转前的前节点(反转后的 后节点)、反转前的后节点(反转后的 前节点)
//下一组 为 反转前的后节点(反转后的 前节点)的 next 以及 next.next
ListNode* swapPairs(ListNode* head) { //入参 反转前的前节点(反转后的 后节点)
////传入的参数的合法性,递归的终止条件
if (NULL==head || NULL==head->next)
return head;
ListNode *res = head->next; //记录 反转前的后节点(反转后的 前节点)
head->next = swapPairs(res->next); //更新 反转后的 后节点 的next 为下一组 反转后的 前节点 (入参为反转前的后节点的next 即为下一组的 反转前的前节点(反转后的 后节点)
res->next = head; //更新 反转后的 前节点的next 为 反转前 的 前节点
return res;
}
};
以【A B C D】为例,那么可分为2组【A B】【C D】递归到最后一层非head->next = NULL那层, ListNode* swapPairs(ListNode* head){}中head为C,head->next为D。
那么就有:
·【C D】组 此时 head 为 C 交换前
ListNode *res = head->next; //D
head->next = swapPairs(res->next); //C->next = D->next=NULL 入参为D->next NULL值跳出递归 返回入参
res->next = head; //D->next = C
return res; //D
此时结果为 【A B D C】
·【A B】组 此时 head 为 A 交换前
ListNode *res = head->next; //B
head->next = D //上次迭代返回值 swapPairs(C)
res->next = head; //B->next = A
return res; //B
此时结果为 【B A D C】
其他情况可同上分析
Java实现
Java实现逻辑上与C++无区别
1、迭代实现 Java
两两交换其中相邻的节点(Swap Nodes in Pairs) Java 迭代实现
2、递归实现 Java
两两交换其中相邻的节点(Swap Nodes in Pairs) Java 递归实现
GitHub链接:
https://github.com/lichangke/LeetCode
个人Blog:
https://lichangke.github.io/
欢迎大家来一起交流学习