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

【LeetCode_206】反转链表

刷爆LeetCode系列

  • LeetCode第206题:反转链表
  • github地址
  • 前言
  • 题目描述
  • 题目与思路分析
    • 思路一:反转链表的指针指向
    • 思路二:取链表的结点,头插到新链表中
  • 代码实现
    • 思路一:反转指针指向
      • 以下两种写法是保存curNext指针的方式不同
    • 思路二:取原链表中的节点,头插到新链表
    • 试错代码
  • 算法代码优化
    • 思路一优化:

LeetCode第206题:反转链表

github地址

有梦想的电信狗

前言

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


题目描述

  • 题目链接:https://leetcode-cn.com/problems/reverse-linked-list/description/

在这里插入图片描述

在这里插入图片描述


题目与思路分析

目标分析

  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
class Solution {
public:ListNode* reverseList(ListNode* head) {// 空链表的情况if(head == nullptr)return nullptr;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的解引用,即使为空也不影响
// 思路一、反转指针
class Solution {
public:ListNode* reverseList(ListNode* head) {if(head == nullptr)return nullptr;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;}
};

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

  • 取链表中的节点,头插到新链表
// 思路二、取链表中的节点,头插到新链表
class Solution {
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无法移动到下一个结点
// 思路二  取结点,头插到新链表中
class Solution {
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;}
};
  • 纠错后的代码
// 思路二  取结点,头插到新链表中
class Solution {
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
// 思路一、反转指针
class Solution {
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;}
};
  • 思路二已经足够简洁正确,无需优化

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

分享到此结束啦
一键三连,好运连连!

你的每一次互动,都是对作者最大的鼓励!


征程尚未结束,让我们在广阔的世界里继续前行! 🚀

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

相关文章:

  • 品牌网站建设 磐石网络的确好沈阳唐朝网络的服务内容
  • LeetCode 215. 数组中的第K个最大元素
  • 老年实训室建设:筑牢老年护理专业学员的实操能力基础
  • 【深度学习新浪潮】基于Qwen3-8B入门LoRA完整指南
  • 数据库设计与UML图
  • 影视网站的设计与实现新泰程序开发
  • 阿里pdf解析方案Logics-Parsing如何用RL攻克复杂文档解析
  • MySQL 索引失效的常见场景与原因分析
  • 四川省建设厅网站川北医学院网页制作员工作厂家
  • 从直线到环形:解锁栈、队列背后的空间与效率平衡术
  • 操作系统全解析:Windows、macOS与Linux的深度对比与选择指南(AI)
  • 网站建设推广ppt模板网站模版防被偷
  • [创业之路-647]:互联网行业的产业链
  • 甘肃省省经合局网站建设的通知知乎app开发公司
  • 计算机视觉与深度学习 | MASt3R 前馈视觉模型:原理、公式与代码实现全解析
  • 作品展示网站源码贵阳企业网站设计制作
  • 【Linux 系统】命令行参数和环境变量
  • 如何用wordpress建一个网站太原建站模板搭建
  • DNS优选 2.6.3 |解锁专业版,优选最快DNS,享受快速且私密的互联网浏览体验
  • 云浮源峰网站建设工作室地址百度免费咨询
  • wordpress 公司网站有赞分销模式佣金
  • 冀icp 网站建设做seo哪些网站会好点
  • 基于YOLOv8-OBB的SAR图像目标检测系统
  • 《强化学习数学原理》学习笔记4——贝尔曼最优方程推理过程
  • 如何缩小物联网设备的 Docker 镜像
  • 513.找树左下角的值(二叉树算法题)
  • LeetCode:84.完全平方数
  • 《API网关性能优化指南:从请求拥堵到毫秒级响应,并发下的架构重构实践》
  • 免费p2p网站建设企业管理系统开发平台
  • 报告派研读:2025年电力设备及新能源行业深度报告