首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >递归-24.两两交换链表中的节点-力扣(LeetCode)

递归-24.两两交换链表中的节点-力扣(LeetCode)

作者头像
白天的黑夜
发布2025-10-22 17:34:54
发布2025-10-22 17:34:54
4500
代码可运行
举报
运行总次数:0
代码可运行
个人主页

专栏:力扣刷题录_1白天的黑夜1的博客-CSDN博客企鹅程序员:Linux 系统与网络编程_1白天的黑夜1的博客-CSDN博客

目录

一、题目解析

1、链表中节点的数目在范围 [0, 100] 内

2、0 <= Node.val <= 100

3、只能进行节点的交换,不能修改节点内部的值

二、算法原理

解法:递归

以宏观视角待递归

通过上面的图片,我们可以知道需要经过三个阶段

1、将前两个节点后的链表通过递归函数进行两两交换,并返回头指针

2、保存第二个节点的指针,用于做新的头指针

3、将前两个节点交换,最后链接上递归函数的头指针,返回新的头指针

如何编写递归代码?

1、重复的子问题->函数头

2、只关心某一个子问题做什么->函数体

3、递归函数的出口

结合视角、如何写递归代码和自己的思路,可以先自己尝试一下编写代码,提升自己的代码能力,题目链接如下

三、代码示例

四、递归展开图

看到最后,如果对您有所帮助,还请点赞、收藏和关注一键三连,在未来还会继续带来优秀的内容,感谢观看,我们下期再见!


一、题目解析

1、链表中节点的数目在范围 [0, 100]

2、0 <= Node.val <= 100

3、只能进行节点的交换,不能修改节点内部的值

二、算法原理

本题也有迭代(循环)的解法,本篇博客会着重讲递归的思路与代码,话不多说开始进入正题。

解法:递归

以宏观视角待递归

该题的思路和206. 反转链表 - 力扣(LeetCode)类似,只不过一个是将所有反转,一个是两个两个的反转。先将前两个节点后的链表进行两两反转,然后返回一个头指针。此时通过一个ListNode*类型的变量newhead保存第二个节点,然后将第二个节点的next指向第一个节点,第一个节点的next指向递归函数返回的头指针。

通过上面的图片,我们可以知道需要经过三个阶段
1、将前两个节点后的链表通过递归函数进行两两交换,并返回头指针
2、保存第二个节点的指针,用于做新的头指针
3、将前两个节点交换,最后链接上递归函数的头指针,返回新的头指针

如何编写递归代码?

1、重复的子问题->函数头

我们的重复子问题就是将链表两两交换,需要一个ListNode*的参数,由于需要返回新的头指针,所以返回值类型是ListNode*。所以题目提供的函数可以拿过来用。

2、只关心某一个子问题做什么->函数体

我们需要一个ListNode*型的变量tmp接受递归函数的返回值,还需要一个ListNode*型的变量newhead记录第二个节点的地址也就是head->next,然后将它们三个链接起来,返回newhead这个新的头指针

3、递归函数的出口

如果一个递归函数没有一个出口(返回值),会使递归层数过多导致栈溢出。当节点为空时,直接返回nullptr;如果节点的next为空,则直接返回节点本身。

结合视角、如何写递归代码和自己的思路,可以先自己尝试一下编写代码,提升自己的代码能力,题目链接如下

24. 两两交换链表中的节点 - 力扣(LeetCode)

三、代码示例

这是递归版的代码,可以和下面迭代版的代码做一下比较

代码语言:javascript
代码运行次数:0
运行
复制
class Solution {
public:
    ListNode* swapPairs(ListNode* head)
    {
        if(head == nullptr) return nullptr;
        if(head->next == nullptr) return head;
        ListNode* tmp = nullptr;
        tmp = swapPairs(head->next->next);
        ListNode* newhead = head->next;//保存新的头指针
        newhead->next = head;
        head->next = tmp;
        return newhead;
    }
};

迭代版的代码

代码语言:javascript
代码运行次数:0
运行
复制
class Solution {
public:
    ListNode* swapPairs(ListNode* head)
    {
        if(head == nullptr || head->next == nullptr) return head;//0or1个节点
        ListNode* newhead = new ListNode();
        ListNode* tail = newhead;
        ListNode* cur1 = head;
        ListNode* cur2 = head->next;
        ListNode* nnext = cur2->next;
        while(cur1!=nullptr && cur2!=nullptr)
        {
            tail->next = cur2;
            cur2->next = cur1;
            cur1->next = nnext;
            tail = cur1;
            cur1=cur1->next;
            if(cur1 == nullptr) break;
            else cur2 = cur1->next;
            if(cur2 != nullptr) 
                nnext = cur2->next;
        }
        return newhead->next;    
    }
};

可以看的出来递归版的代码量明显变少了,而且少命名了一些变量,节约了空间

四、递归展开图

我们画递归展开图的目的是为了去体会函数执行和调用的过程,所以样例可以不用很复杂。这张递归展开图使用题目给的示例1 1->2->3->4->nullptr

关键点为需要保存第二个节点的地址,不然在更改指针指向时,会丢失节点的地址,导致链接出错;以及函数出口的判断传入的是head->next->next,避免出现对空指针进行访问操作

看到最后,如果对您有所帮助,还请点赞、收藏和关注一键三连,在未来还会继续带来优秀的内容,感谢观看,我们下期再见!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-10-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、题目解析
    • 1、链表中节点的数目在范围 [0, 100] 内
    • 2、0 <= Node.val <= 100
    • 3、只能进行节点的交换,不能修改节点内部的值
  • 二、算法原理
    • 解法:递归
      • 以宏观视角待递归
      • 通过上面的图片,我们可以知道需要经过三个阶段
    • 如何编写递归代码?
      • 1、重复的子问题->函数头
      • 2、只关心某一个子问题做什么->函数体
      • 3、递归函数的出口
    • 结合视角、如何写递归代码和自己的思路,可以先自己尝试一下编写代码,提升自己的代码能力,题目链接如下
  • 三、代码示例
  • 四、递归展开图
    • 看到最后,如果对您有所帮助,还请点赞、收藏和关注一键三连,在未来还会继续带来优秀的内容,感谢观看,我们下期再见!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档