当前位置: 首页 > news >正文

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

个人主页:1白天的黑夜1-CSDN博客

专栏:力扣刷题录_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)

三、代码示例

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

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;}
};

迭代版的代码

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,避免出现对空指针进行访问操作

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

http://www.dtcms.com/a/499501.html

相关文章:

  • 【Java零基础·第12章】Lambda与Stream API
  • Qemu-NUC980(八):GPIO Controller
  • 外贸型企业网站建设开源商城源码
  • JS逆向-安全辅助项目Yakit热加载魔术方法模版插件语法JSRpc进阶调用接口联动
  • 使用IOT-Tree接入各种数据转BACnet模拟设备输出
  • 网站搭建说明北京海淀区是几环
  • 基于多模态AI技术的传统行业智能化升级路径研究——以开源AI大模型、AI智能名片与S2B2C商城小程序为例
  • 【C语言进阶】指针进阶_数组指针的使用,数组参数和指针参数
  • PySide6 控件插入日期时间(QDateTime)
  • 网站建设 jsp php垂直网站建设
  • 招商网站大全企业官方网站建设的流程
  • 征程 6 | 工具链如何支持 Matmul/Conv 双 int16 输入量化?
  • 【案例实战】鸿蒙分布式调度:跨设备协同实战
  • 中英文网站设计网站开发投标文件
  • Langgraph译文1:让AI自主决策的代理架构
  • 如何让百度能查到自己衡阳专业的关键词优化终报价
  • 为什么.NET的System.IO.Compression无法解压zlib流
  • 微信小程序:日常零售供应系统
  • 安卓如何查看settings是被哪个进程更新的?相关dumpsys命令剖析
  • 网络营销方式案例分析郑州网站优化推广
  • 下载软件太慢的加速操作
  • 网站改版技术要求git wordpress中文免费主题
  • 从应力到位移:混合模式分层损伤起始点推导
  • Gartner 2025年新兴技术成熟度曲线
  • HCIA DAY2
  • 【Go】--文件上传
  • 基于SpringBoot及PostgreSQL的国家减肥食谱管理项目(中):食谱与菜单配置搭建
  • 网站建设 需要准备材料安徽六安特产有哪些
  • Qt的QT_QPA_EGLFS_INTEGRATION环境变量浅解
  • ppt设计网站有哪些银行管理系统网站建设