【LeetCode_206】反转链表

【LeetCode_206】反转链表

刷爆LeetCode系列

LeetCode第206题:反转链表

github地址

有梦想的电信狗

前言

本文用C++实现LeetCode206题:反转链表


题目描述

在这里插入图片描述
在这里插入图片描述

题目与思路分析

目标分析

  1. 有单链表的头节点 head ,反转原链表
  2. 返回反转后的链表的头指针
  3. 提高要求:时间复杂度为O(n),空间复杂度为O(1)

思路一:反转链表的指针指向

思路:遍历一遍链表,将当前结点的next指针,指向其前驱节点,即可实现链表的反转。最终返回链表的最后一个节点即可(原链表的最后一个结点作为新链表的头结点

操作

  • head == nullptr时,为空链表,直接return nullptr;
  • 遍历链表
    • curNode:从头结点head开始,依次遍历链表,更改指针的指向
      • 当前结点的next指针,指向其前驱节点,因此需要提前保存当前结点的前驱节点
    • curPrev:记录curNode的前驱节点,方便反转指针指向,初始值为nullptr
    • curNext:提前保存curNode的后继结点,防止反转指针指向curNode无法移动到下一个结点
  • 更改指向
    • 保存curNode的下一个结点ListNode* curNext = curNode->next
    • 更改当前结点的next指针curNode->next = curPrev
    • curPrev和curNode依次向后移动
      • curPrev = curNode;
      • curNode = curNext;
  • 最终return curPrevcurPrev最后的位置就是链表的尾结点
在 while 循环内保存 curNext,保证了 curNode 一定不为空,避免了对空指针解引用可以保证一定可以取到 curNext,为空或非空
在这里插入图片描述
  • 链表只有一个结点的情况
在这里插入图片描述

思路二:取链表的结点,头插到新链表中

思路:创建一个新链表,头结点为newHead,初始为nullptr。遍历原链表,将原链表中的节点依次头插到新链表中,头插后更新newHead,即可实现链表的反转,最终返回newHead

操作

  • 遍历链表
    • curNode:从头结点head开始,依次遍历链表,进行头插操作。将当前结点的next指针,指向新链表的newHead,再更新newHead的值。之后curNode移向下一个结点。由于头插后curNode->next的值更改,不能通过curNode = curNode->next的方式移动,因此需要提前保存curNode的后继节点
    • curNext:提前保存curNode的后继结点,防止头插curNode无法移动到下一个结点
  • 头插
    • 保存curNode的下一个结点ListNode* curNext = curNode->next
    • 更改当前结点的next指针curNode->next = newHead
    • 更新newHead的值newHead = curNode;
    • curNode向后移动curNode = curNext;
  • 最终return newHeadnewHead即为新链表的头结点
在 while 循环内保存 curNext,保证了 curNode 一定不为空,避免了对空指针解引用可以保证一定可以取到 curNext,为空或非空
在这里插入图片描述

代码实现

思路一:反转指针指向

以下两种写法是保存curNext指针的方式不同

  • 在while循环外保存curNext指针,初始值可能为nullptr
classSolution{public: ListNode*reverseList(ListNode* head){// 空链表的情况if(head ==nullptr)returnnullptr; ListNode* curNode = head; ListNode* curPrev =nullptr; ListNode* curNext = head->next;// 链表只有一个结点的情况if(curNext ==NULL)return head;while(curNode){ curNode->next = curPrev; curPrev = curNode; curNode = curNext;// curNext可能为空,需要判断 非空时再向后移动if(curNext) curNext = curNext->next;}return curPrev;}};
  • 在while循环外保存curNext指针:不涉及对curNext的解引用,即使为空也不影响
// 思路一、反转指针classSolution{public: ListNode*reverseList(ListNode* head){if(head ==nullptr)returnnullptr; ListNode* curNode = head; ListNode* curPrev =nullptr;while(curNode){// 在 while 循环内保存 curNext,保证了 curNode 一定不为空,避免了对空指针解引用// 可以保证一定可以取到 curNext ,为空或非空 ListNode* curNext = curNode->next; curNode->next = curPrev; curPrev = curNode; curNode = curNext;}return curPrev;}};

思路二:取原链表中的节点,头插到新链表

  • 取链表中的节点,头插到新链表
// 思路二、取链表中的节点,头插到新链表classSolution{public: ListNode*reverseList(ListNode* head){ ListNode* newHead =nullptr,*curNode = head;while(curNode){// 提前保存 curNode 的下一个结点 ListNode* curNext = curNode->next;// 头插 curNode->next = newHead; newHead = curNode;// curNode 向后移动 curNode = curNext;}return newHead;}};

试错代码

  • 初次尝试时的错误代码:
  • 错误原因:
    • 第一次头插后,链表直接断开了,curNode无法移动到下一个结点
// 思路二 取结点,头插到新链表中classSolution{public: ListNode*reverseList(ListNode* head){ ListNode* newHead =nullptr; ListNode* curNode = head;while(curNode){// 错误原因,第一次头插后,链表直接断开了,curNode无法移动到下一个结点if(newHead ==nullptr){ newHead = curNode; newHead->next =nullptr;}else{ curNode->next = newHead; newHead = curNode;} curNode = curNode->next;}return newHead;}};
  • 纠错后的代码
// 思路二 取结点,头插到新链表中classSolution{public: ListNode*reverseList(ListNode* head){ ListNode* newHead =nullptr; ListNode* curNode = head;while(curNode){ ListNode* curNext = curNode->next;// 提前保存 下一个结点if(newHead ==nullptr){ newHead = curNode; newHead->next =nullptr;}else{ curNode->next = newHead; newHead = curNode;} curNode = curNext;}return newHead;}};

算法代码优化

思路一优化:

  • 优化点:无需单独判断链表为空时的情况
    • 链表为空时不进入while循环,直接返回 curPrev,而 curPrev 初始值为 nullptr
// 思路一、反转指针classSolution{public: ListNode*reverseList(ListNode* head){ ListNode* curNode = head,*curPrev =nullptr;while(curNode){// 在 while 循环内保存 curNext,保证了 curNode 一定不为空,避免了对空指针解引用// 可以保证一定可以取到 curNext ,为空或非空 ListNode* curNext = curNode->next; curNode->next = curPrev; curPrev = curNode; curNode = curNext;}return curPrev;}};
  • 思路二已经足够简洁正确,无需优化

以上就是本文的所有内容了,如果觉得文章对你有帮助,欢迎 点赞⭐收藏 支持!如有疑问或建议,请在评论区留言交流,我们一起进步

分享到此结束啦
一键三连,好运连连!
你的每一次互动,都是对作者最大的鼓励!征程尚未结束,让我们在广阔的世界里继续前行! 🚀

Read more

做鸿蒙 App 一个月:10 个 ArkUI 大坑

做鸿蒙 App 一个月:10 个 ArkUI 大坑

子玥酱(掘金 / 知乎 / ZEEKLOG / 简书 同名) 大家好,我是子玥酱,一名长期深耕在一线的前端程序媛 👩‍💻。曾就职于多家知名互联网大厂,目前在某国企负责前端软件研发相关工作,主要聚焦于业务型系统的工程化建设与长期维护。 我持续输出和沉淀前端领域的实战经验,日常关注并分享的技术方向包括前端工程化、小程序、React / RN、Flutter、跨端方案, 在复杂业务落地、组件抽象、性能优化以及多端协作方面积累了大量真实项目经验。 技术方向:前端 / 跨端 / 小程序 / 移动端工程化 内容平台:掘金、知乎、ZEEKLOG、简书 创作特点:实战导向、源码拆解、少空谈多落地 文章状态:长期稳定更新,大量原创输出 我的内容主要围绕 前端技术实战、真实业务踩坑总结、框架与方案选型思考、行业趋势解读 展开。文章不会停留在“API 怎么用”,而是更关注为什么这么设计、在什么场景下容易踩坑、

By Ne0inhk
Flutter 三方库 appstream 的鸿蒙化适配指南 - 驾驭 Linux 生态元数据规范,打造高性能、标准化、国际化的 OpenHarmony 桌面应用商店分发基石

Flutter 三方库 appstream 的鸿蒙化适配指南 - 驾驭 Linux 生态元数据规范,打造高性能、标准化、国际化的 OpenHarmony 桌面应用商店分发基石

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 三方库 appstream 的鸿蒙化适配指南 - 驾驭 Linux 生态元数据规范,打造高性能、标准化、国际化的 OpenHarmony 桌面应用商店分发基石 前言 随着鸿蒙(OpenHarmony)生态向 PC 和平板端的高速扩张,如何为海量的三方软件建立一套标准化的“数字档案”,成了构建应用商店生态的核心痛点。过去,开发者提交应用信息时,往往采用碎片化的 JSON 或自定义文档。这会导致软件分发时详情页展示不一、多语言支持混乱,甚至连基本的截图和版本日志都难以对齐。 为了解决这个问题,我们需要引入一套具备全球化视野的元数据定义标准。appstream 作为 Linux 生态下最重要的应用信息描述规范,能够通过结构化的 XML 标签,精准定义软件的身世、功能和展示资产。适配到鸿蒙平台后,它不仅能让你的重型“鸿蒙私有应用商店”瞬间具备吞金般的解析能力,

By Ne0inhk
Flutter 组件 sse_stream 的适配 鸿蒙Harmony 实战 - 驾驭轻量级服务器发送事件流、实现鸿蒙端长连接实时通讯与断线重连方案

Flutter 组件 sse_stream 的适配 鸿蒙Harmony 实战 - 驾驭轻量级服务器发送事件流、实现鸿蒙端长连接实时通讯与断线重连方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 sse_stream 的适配 鸿蒙Harmony 实战 - 驾驭轻量级服务器发送事件流、实现鸿蒙端长连接实时通讯与断线重连方案 前言 在鸿蒙(OpenHarmony)生态的金融实时行情、在线社交协作以及物联网告警应用中,如何实现“数据从服务器到终端的实时推送”是一个核心命题。面对不需要双向通信(WebSocket 太重)且对功耗极其敏感的移动端场景,基于 HTTP 协议的轻量化长连接方案——SSE(Server-Sent Events)成为了事实上的行业标准。 然而,处理不稳定的移动网络波动、处理分块传输(Chunked Encoding)中的字节截断、以及在鸿蒙端实现优雅的断线重连逻辑,依然是开发者面临的技术瓶颈。 sse_stream 是一套专为解析该协议设计的高性能响应流解析引擎。它能将原始的二进制流瞬间转化为语义化的 Event 对象。适配到鸿蒙平台后,它不仅能支撑起一个毫秒级延迟的行情大盘,

By Ne0inhk
【汉化中文版】OpenClaw(Clawdbot/Moltbot)第三方开源汉化中文发行版部署全指南:一键脚本/Docker/npm 三模式安装+Ubuntu 环境配置+中文汉化界面适配开源版

【汉化中文版】OpenClaw(Clawdbot/Moltbot)第三方开源汉化中文发行版部署全指南:一键脚本/Docker/npm 三模式安装+Ubuntu 环境配置+中文汉化界面适配开源版

OpenClaw这是什么? OpenClaw(曾用名 Clawdbot / Moltbot)是一个开源的个人 AI 助手平台(GitHub 120k+ Stars),可以通过 WhatsApp、Telegram、Discord 等聊天软件与 AI 交互。简单说就是:在你自己的机器上运行一个 AI 助手,通过常用聊天软件跟它对话。 forks项目仓库 :https://github.com/MaoTouHU/OpenClawChinese 文章目录 * OpenClaw这是什么? * 汉化效果预览 * 环境要求 * 安装方式 * 方式 A:一键脚本(推荐新手) * 方式 B:npm 手动安装 * 方式 C:Docker 部署(服务器推荐) * 首次配置 * 运行初始化向导 * 安装守护进程(

By Ne0inhk