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结点交换位置后,再连起来。