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

本文介绍了一种使用递归方法在链表中交换相邻节点的技术,而不直接交换它们的值。文章详细阐述了解决方案的思路,并提供了一个具体的C++实现案例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题详情

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;
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值