目錄鏈接:http://www.lxweimin.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/
歡迎大家來一起交流學習