一、题目介绍
题目链接(力扣上第24题)
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例:
二、两种方法
迭代法:
ListNode* swapPairs(ListNode* head) {
if(head==NULL||head->next==NULL)
return head;
ListNode* dummy=new ListNode(0,head);
ListNode* pre=dummy;
ListNode* cur=head;
while(cur&&cur->next)
{
ListNode* next=cur->next;
pre->next=next;
cur->next=next->next;
next->next=cur;
pre=cur;
cur=cur->next;
}
head=dummy->next;
delete dummy;
return head;
}
思路:
1.先从结点数少时想起:当没有结点或者只有一个结点时,直接返回head就可以了.
2.当有两个或者三个结点时(可以代表一般情况):
定义三个指针:
cur:需要交换的两个结点中的前一个结点;
next:cur的下一个结点,即两个结点中的后一个结点;
pre:cur的前一个结点,用来连接需要交换的两个结点:
主要算法步骤:
1.pre->next=next; cur->next=next->next; next->next=cur; 结点交换连接过程;
2.pre=cur; cur=cur->next; 遍历过程;
3.while(cur&&cur->next) 循环判断条件,当当前遍历.的需要交换的一组结点中的第一个结点或者第二个结点为空时,结束循环;(其实一开始对head的判断可以省略,这里也可以判断);
细节:
1.由于有pre->next=next操作,但是当交换第一组结点时,前面没有结点,故需要定义一个哨兵位结点dummy,并给pre赋值为dummy;
2.next在循环里定义就好了,直接next=cur->next即可,不用在while循环开始前就定义;
递归法:
ListNode* swapPairs(ListNode* head) {
if(head==NULL||head->next==NULL)
return head;
ListNode* second=head->next;
head->next=swapPairs(second->next);
second->next=head;
return second;
}
思路:
递归三部曲:
1.确定函数返回值和函数参数:每次返回交换后的一组结点中的前一个结点,使交换后的一组结点能够与其前面的结点连接;每次传递的参数为需要交换的一组结点中的前一个结点;
2.判断终止条件:很显然,当每一组需交换结点组中的head或者head->next为NULL时,终止;
3.单层递归逻辑:每次传参为需交换结点组中的前一个结点,以第一次归的过程思考,函数的返回值要么为空,要么为最后一个结点(链表中结点个数为奇数),再想想交换过程,即head->next=返回值,second->next=head;此时second为结点组中的第一个结点,再返回second,让上一个结点组进行相同操作,最终返回的second即为整个交换后链表的头结点;