LeetCode 24. 兩兩交換鏈表中的節點(Swap Nodes in Pairs)

LeetCode.jpg

目錄鏈接: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

知乎個人首頁:
https://www.zhihu.com/people/lichangke/

簡書個人首頁:
http://www.lxweimin.com/u/3e95c7555dc7

個人Blog:
https://lichangke.github.io/

歡迎大家來一起交流學習

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。