问题详情
Given a linked list, swap every two adjacent nodes and return its head.
For example,
Given 1->2->3->4, you should return the list as 2->1->4->3.
Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.
结点结构为:
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
问题分析及思路
最近忙期中的事,大概已经半个多月没有碰过leetcode了,这是新的一道题,后面会多打一些。
这道题大致意思是将一个链表中相邻两个结点相交换,但是不能直接交换它们的值,必须交换它们的结点。刚开始接触这道题我尝试用一个while循环来做它,却发现非常复杂,几乎写不出while循环来实现它。
认真思考后我发现这是一个递归问题,正好递归一直是我的弱项,这道题可以锻炼我的递归能力。
最后算法思路如下:
1.对函数swapTwoPairs传入一个结点First,当First的下下个结点不为空时,用结点Second保存它的下下个结点,Third保存它的下一个结点。使得First的下下个结点变为它自己,First的下个结点变为swapTwoPairs(Second)递归。递归完成后返回Third。
2.当First的下下个结点为空时,用Third保存它的下个结点,使得First的下下个结点变为它自己,它的下个结点为NULL,返回Third。
以上算法思路有漏洞,只考虑了有偶数个结点的情况,没有考虑为奇数个结点的情况,故在算法前还要加一个判断:
如果First的下个结点为NULL,则直接返回First。
此外还要注意,当传入一个空的链表时,还要检查是否为空。为空就不进入递归,直接返回NULL。
由于本人对递归十分不熟悉,这道题收获很多,它的递归次数大概是n个结点数除以2,即log2n次,时间复杂度为O((log2n)2)。
具体代码
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(head == NULL) {
return NULL;
}
return swapTwoPairs(head);
}
ListNode* swapTwoPairs(ListNode* First) {
if(First->next == NULL) {
return First;
}
if(First->next->next != NULL) {
ListNode* Second = First->next->next;
ListNode* Third = First->next;
First->next->next = First;
First->next = swapTwoPairs(Second);
return Third;
} else {
First->next->next = First;
ListNode* Third = First->next;
First->next = NULL;
return Third;
}
}
};