11. 断藕重连术 - 反转链表(迭代与递归)

news/2025/2/24 22:29:58

哪吒在数据修仙界中继续他的修炼之旅。这一次,他来到了一片神秘的藕断湖,湖面上漂浮着一串串断裂的莲藕,每段莲藕上都刻着数字。湖中央有一座巨大的石碑,上面刻着一行文字:“欲破此湖,需以断藕重连术,反转链表,迭代与递归并用。”

哪吒定睛一看,石碑上还有一行小字:“链表1 -> 2 -> 3 -> 4反转后为4 -> 3 -> 2 -> 1。”哪吒心中一动,他知道这是一道关于反转链表的难题,需要将链表中的节点顺序完全反转。

暴力解法:断藕重连术的初次尝试

哪吒心想:“要反转链表,我可以逐个节点遍历,将每个节点的指针反转。”他催动断藕重连术,从链表的头节点开始,逐个节点遍历,将每个节点的指针指向前一个节点。

ListNode* reverseList(ListNode* head) {
    if (!head || !head->next) return head;  // 如果链表为空或只有一个节点,直接返回
    ListNode* prev = nullptr;
    ListNode* curr = head;
    while (curr) {
        ListNode* next = curr->next;  // 保存下一个节点
        curr->next = prev;            // 反转当前节点的指针
        prev = curr;                  // 更新prev和curr
        curr = next;
    }
    return prev;  // 返回新的头节点
}

哪吒成功地反转了链表,但断藕重连术的光芒却黯淡了下来。他意识到,这种方法虽然可行,但效率较低,尤其是当链表很长时,灵力消耗较大。

C++语法点:链表操作

在C++中,链表是处理动态数据结构的常用工具。以下是一些重要特性:

  • 链表节点
    • 使用ListNode结构体表示链表节点,包含val(节点值)和next(指向下一个节点的指针)。
    • 常用操作:
      • ListNode* head:表示链表的头节点。
      • node->next:访问节点的下一个节点。
  • 链表反转
    • 通过逐个节点遍历,将每个节点的指针指向前一个节点。

高阶优化:递归反转的智慧

哪吒元神中突然浮现金色铭文——「断藕重连,递归反转显神通」。他意识到,可以通过递归的方式,从链表的尾部开始反转,逐步回溯到头部,从而实现链表的反转。

哪吒决定使用递归方法,从链表的头节点开始,逐层递归到链表的尾部,然后逐层回溯,将每个节点的指针指向前一个节点。

开始
递归到链表尾部
是否到达尾部
反转尾部节点
继续递归
回溯并反转指针
返回新头节点
ListNode* reverseList(ListNode* head) {
    if (!head || !head->next) return head;  // 如果链表为空或只有一个节点,直接返回
    ListNode* newHead = reverseList(head->next);  // 递归反转剩余部分
    head->next->next = head;  // 反转当前节点的指针
    head->next = nullptr;     // 将当前节点的next置为nullptr
    return newHead;           // 返回新的头节点
}

复杂度分析:灵力消耗评估

  • 时间复杂度:O(n),因为需要逐个节点遍历链表
  • 空间复杂度:O(1)(迭代法),O(n)(递归法,递归栈空间)。

哪吒使用优化后的代码,断藕重连术的灵力消耗大幅减少,成功破解了藕断湖的难题。

变式训练:阵法变形的应对

  1. 链表为空或只有一个节点:如[][1],直接返回原链表
  2. 链表很长:如长度为1000的链表,验证算法的效率。
  3. 链表中包含重复值:如[1, 2, 2, 3],验证算法的正确性。
  4. 链表为环形链表:如1 -> 2 -> 3 -> 1,验证算法的鲁棒性。

哪吒通过这些变式训练,进一步巩固了对链表反转的理解。

太乙口诀:修炼的智慧

断藕重连,递归反转显神通。
迭代逐节点,递归逐层回溯,链表反转成。

口诀解释

  • 断藕重连:象征链表反转的智慧,通过断藕重连术将链表反转。
  • 递归反转显神通:通过递归的方式,从链表尾部开始反转,逐步回溯到头部。
  • 迭代逐节点:使用迭代法逐个节点反转,适用于空间敏感的场景。
  • 递归逐层回溯:使用递归法逐层反转,代码简洁,但需要注意递归栈空间。
  • 链表反转成:最终完成链表的反转操作,达到预期效果。

文章总结

在这篇文章中,我们跟随小哪吒学习了如何使用迭代和递归方法解决链表反转的问题。通过暴力解法的尝试,哪吒意识到逐个节点反转虽然简单,但效率较低。在太乙真人的指引下,他领悟了递归反转的精髓,通过从链表尾部开始逐层回溯,大大减少了灵力消耗。我们还详细介绍了C++中链表操作的基本方法,包括节点遍历和指针反转。通过这次修炼,哪吒不仅提升了算法能力,还对链表操作有了更深刻的理解。


http://www.niftyadmin.cn/n/5864839.html

相关文章

三:记录日志-设置成守护进程-改为生产环境

接着二:可以完美实现前端与后端的有机结合后 三需要 实现程序上线后,需要记录日志,将程序设置成系统守护进程,方便管理将环境设置为生产环境,在这一步前还是使用的app.run(),不符合生产需要 记录日志 需求&#xff…

开源一款I2C电机驱动扩展板-FreakStudio多米诺系列

总线直流电机扩展板 原文链接: FreakStudio的博客 摘要 设计了一个I2C电机驱动板,通过I2C接口控制多个电机的转速和方向,支持刹车和减速功能。可连接16个扩展板,具有PWM输出、过流过热保护和可更换电机驱动芯片。支持按键控制…

第十章 Kubernetes Ingress

目录 一、四层负载与七层负载 1、工作层次 2、七层负载的应用场景 二、Ingress概念和应用场景 使用Nginx的Ingress内部工作原理图 基于Ingress API的七层实现 三、Ingress安装部署 1、各节点安装2个镜像 2、下载nginx-ingress-controller的chart以及修改values.yaml文…

全面汇总windows进程通信(三)

在Windows操作系统下,实现进程间通信(IPC, Inter-Process Communication)有几种常见的方法,包括使用管道(Pipe)、共享内存(Shared Memory)、消息队列(Message Queue)、命名管道(Named Pipe)、套接字(Socket)等。本文介绍如下几种: RPC(远程过程调用,Remote Pr…

大语言模型(LLM)提示词(Prompt)高阶撰写指南

——结构化思维与工程化实践 一、LLM提示词设计的核心逻辑 1. 本质认知 LLM是「超强模式识别器概率生成器」,提示词的本质是构建数据分布约束,通过语义信号引导模型激活特定知识路径。优秀提示词需实现: 精准性:消除歧义&#…

C#快速幂算法

快速幂算法:数学运算中的 “光速引擎” 在数学运算的奇妙世界里,计算一个数的幂次方是常有的事。想象一下,你要计算 2 的 100 次方,要是按照传统的方法,一个一个地乘,那可得花费不少时间,就像徒…

【亲测有效】百度Ueditor富文本编辑器添加插入视频、视频不显示、和插入视频后二次编辑视频标签不显示,显示成img标签,二次保存视频被替换问题,解决方案

【亲测有效】项目使用百度Ueditor富文本编辑器上传视频相关操作问题 1.百度Ueditor富文本编辑器添加插入视频、视频不显示 2.百度Ueditor富文本编辑器插入视频后二次编辑视频标签不显示,在编辑器内显示成img标签,二次保存视频被替换问题 问题1&#xff1…

Oracle中补全时间的处理

在实际数据处理的过程中,存在日期不连续的问题,可能会导致数据传到前后端出现异常,为了避免这种问题,通常会从数据端进行日期不全的处理: 以下为补全年份的案例: with x as (select 开始年份 (…