算法分析与设计——LeetCode Problem.24 Swap Nodes in Pairs

来源:互联网 发布:手机护眼软件 编辑:程序博客网 时间:2024/06/03 16:57

问题详情

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;        }    }};
原创粉丝点击