LeetCode 24. 兩兩交換鏈表中的節(jié)點(diǎn)(Swap Nodes in Pairs)

LeetCode.jpg

目錄鏈接:http://www.itdecent.cn/p/9c0ada9e0ede

兩兩交換其中相鄰的節(jié)點(diǎn)

LeetCode 24. 兩兩交換鏈表中的節(jié)點(diǎn)(Swap Nodes in Pairs)
給定一個(gè)鏈表,兩兩交換其中相鄰的節(jié)點(diǎn),并返回交換后的鏈表。
你不能只是單純的改變節(jié)點(diǎn)內(nèi)部的值,而是需要實(shí)際的進(jìn)行節(jié)點(diǎn)交換。

示例:
給定 1->2->3->4, 你應(yīng)該返回 2->1->4->3.

切題

一、Clarification
目標(biāo)明確兩兩交換鏈表中的節(jié)點(diǎn),無特別需要注意的邊界但需常規(guī)關(guān)注下空鏈表和只有一個(gè)元素的鏈表

二、Possible solutions
1、迭代

在邊界內(nèi)同時(shí)取出2個(gè)節(jié)點(diǎn)并交換,然后向下移動2位
使用哨兵簡化處理,空鏈表,一個(gè)元素的鏈表

2、遞歸

遞歸終止條件 head 和 head.next 為None
每層遞歸交換當(dāng)前兩節(jié)點(diǎn),并返回 交換后兩個(gè)節(jié)點(diǎn)中的前一個(gè)節(jié)點(diǎn)

Python3 實(shí)現(xiàn)

迭代實(shí)現(xiàn)

兩兩交換其中相鄰的節(jié)點(diǎn)(Swap Nodes in Pairs) Py3 迭代實(shí)現(xiàn)

#@author:leacoder
#@des: 循環(huán)實(shí)現(xiàn)  多元賦值

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  # 記錄 要交換的兩節(jié)點(diǎn)
            pre.next,b.next,a.next,= b,a,b.next # 2個(gè)節(jié)點(diǎn)交換,注意哨兵的next改變了
            pre = a # 向下移動2位
        return retult.next

遞歸實(shí)現(xiàn)

#@author:leacoder
#@des: 遞歸實(shí)現(xiàn)  多元賦值
class Solution:
    def swapPairs(self, head: ListNode) -> ListNode:
        if not head or not head.next:
            return head
        resultmp = self.swapPairs(head.next.next) # 下移兩位  返回 值為兩兩交換后  兩個(gè)節(jié)點(diǎn)中的前一個(gè)節(jié)點(diǎn)
        # 交換 當(dāng)前兩節(jié)點(diǎn)
        A, B = head, head.next # 當(dāng)前兩節(jié)點(diǎn)
        A.next, B.next = resultmp,A # 交換
        return  B   # 返回 兩兩交換后  兩個(gè)節(jié)點(diǎn)中的前一個(gè)節(jié)點(diǎn)

C++實(shí)現(xiàn)

1、迭代實(shí)現(xiàn) C++

兩兩交換其中相鄰的節(jié)點(diǎn)(Swap Nodes in Pairs) C++ 迭代實(shí)現(xiàn)

 * @author:leacoder
 * @des: 迭代實(shí)現(xiàn) 兩兩交換鏈表中的節(jié)點(diǎn)
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        /*在頭節(jié)點(diǎn)前 新建一節(jié)點(diǎn),其next指向head。好處 將[]\[1]這種特殊情況能夠統(tǒng)一處理*/
        ListNode *virtualnode = new ListNode(0);
        virtualnode->next = head;
        
        ListNode *node = virtualnode;//存儲新的開始節(jié)點(diǎn)
        
        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、遞歸實(shí)現(xiàn) C++

兩兩交換其中相鄰的節(jié)點(diǎn)(Swap Nodes in Pairs) C++ 遞歸實(shí)現(xiàn)

/**
 * @author:leacoder
 * @des: 遞歸實(shí)現(xiàn) 兩兩交換鏈表中的節(jié)點(diǎn)
 */
class Solution {
public:
    //每兩個(gè)節(jié)點(diǎn)為一組  反轉(zhuǎn)前的前節(jié)點(diǎn)(反轉(zhuǎn)后的 后節(jié)點(diǎn))、反轉(zhuǎn)前的后節(jié)點(diǎn)(反轉(zhuǎn)后的 前節(jié)點(diǎn))
    //下一組 為 反轉(zhuǎn)前的后節(jié)點(diǎn)(反轉(zhuǎn)后的 前節(jié)點(diǎn))的 next 以及 next.next
    ListNode* swapPairs(ListNode* head) { //入?yún)?反轉(zhuǎn)前的前節(jié)點(diǎn)(反轉(zhuǎn)后的 后節(jié)點(diǎn))
        ////傳入的參數(shù)的合法性,遞歸的終止條件
        if (NULL==head || NULL==head->next) 
            return head; 
        ListNode *res = head->next; //記錄 反轉(zhuǎn)前的后節(jié)點(diǎn)(反轉(zhuǎn)后的 前節(jié)點(diǎn))
        head->next = swapPairs(res->next); //更新 反轉(zhuǎn)后的 后節(jié)點(diǎn) 的next  為下一組 反轉(zhuǎn)后的 前節(jié)點(diǎn)  (入?yún)榉崔D(zhuǎn)前的后節(jié)點(diǎn)的next 即為下一組的 反轉(zhuǎn)前的前節(jié)點(diǎn)(反轉(zhuǎn)后的 后節(jié)點(diǎn))
        res->next = head; //更新 反轉(zhuǎn)后的 前節(jié)點(diǎn)的next 為 反轉(zhuǎn)前 的 前節(jié)點(diǎn)
        
        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】組 此時(shí) head 為 C  交換前
        ListNode *res = head->next;   //D
        head->next = swapPairs(res->next); //C->next = D->next=NULL 入?yún)镈->next   NULL值跳出遞歸 返回入?yún)?
        res->next = head; //D->next = C
        return res; //D
        此時(shí)結(jié)果為 【A B D C】
      ·【A B】組 此時(shí) head 為 A  交換前
        ListNode *res = head->next;   //B
        head->next = D //上次迭代返回值   swapPairs(C)
        res->next = head; //B->next = A
        return res; //B
        此時(shí)結(jié)果為 【B A D C】

其他情況可同上分析

Java實(shí)現(xiàn)

Java實(shí)現(xiàn)邏輯上與C++無區(qū)別

1、迭代實(shí)現(xiàn) Java

兩兩交換其中相鄰的節(jié)點(diǎn)(Swap Nodes in Pairs) Java 迭代實(shí)現(xiàn)

2、遞歸實(shí)現(xiàn) Java

兩兩交換其中相鄰的節(jié)點(diǎn)(Swap Nodes in Pairs) Java 遞歸實(shí)現(xiàn)


GitHub鏈接:
https://github.com/lichangke/LeetCode

知乎個(gè)人首頁:
https://www.zhihu.com/people/lichangke/

簡書個(gè)人首頁:
http://www.itdecent.cn/u/3e95c7555dc7

個(gè)人Blog:
https://lichangke.github.io/

歡迎大家來一起交流學(xué)習(xí)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容