leetcode_数据解构_链表_24两两交换链表中的结点(递归初步2)

递归初步见:

https://www.cnblogs.com/San-Francisco/p/14882647.html

题目:

https://leetcode-cn.com/problems/swap-nodes-in-pairs/

两两交换链表中的结点,分别用了1.递归 2.迭代 两个方法解决该问题

1.递归:

/**
 * 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)return NULL;
        else if(!(head->next))return head;
        else{
            ListNode *p=head->next;
            head->next=swapPairs(head->next->next);
            p->next=head;
            return p;
        }
    }
};

递归的结束条件:当链表中无结点,或者只有一个结点时,不需要再递归下去了,无结点时,返回给上一层NULL,只有一个结点时,不需要交换位置,返回给上一次该结点本身。

递归的每一级要做的事情:

如果满足递归结束条件则结束,如果不满足,则交换该层的两个结点位置,并且返回给上一“两个结点交换后,位于较前位置的结点”,如下图所示:

 

 

2.迭代

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(!head||!head->next)return head;
        ListNode *dummy=new ListNode(0,head);
        ListNode *pre=dummy;
        ListNode *p=head,*pp=head->next,*newHead=head->next;
        while(p&&pp){
            p->next=pp->next;
            pp->next=p;
            pre->next=pp;
            pre=p;
            p=pre->next;
            if(p)
            pp=p->next;
        }
        ListNode *ans=dummy->next;
        delete dummy;
        return ans;
        
    }

设置一个哑结点dummy,指向head,将pre结点指向dummy,然后再设置p和pp结点,总体思想如下:一共3个工作结点pre,p,pp,pre指向已经完成交换好的上面一组结点(其实一组结点就是两个结点)的最后一个结点,p指向本次需要交换的第一个结点,pp指向本次需要交换的第二个结点;将p和pp结点交换位置后,再连起来。

 

posted @ 2021-06-15 15:19  SanFranciscoo  阅读(33)  评论(0编辑  收藏  举报