每日算法随笔:反转链表

news/2025/1/15 21:56:58/文章来源:https://www.cnblogs.com/yubaibaibubai/p/18406442

题解:反转链表

这道题目要求我们将一个单链表进行反转,返回反转后的链表。链表的反转可以通过 迭代递归 两种方法来实现。下面我们将详细解释这两种方法,并通过例子演示每一步的变化过程。

方法一:迭代法

思路

  • 我们用三个指针来完成链表的反转:prev 表示前一个节点,curr 表示当前节点,next 表示下一个节点。
  • 通过不断将当前节点的 next 指针指向 prev,实现链表的逐步反转。

迭代的步骤

  1. 初始化 prev = nullcurr = head,然后开始遍历链表。
  2. 在每次迭代中,先用 next 保存 curr.next,避免链表断开。
  3. curr.next 指向 prev,反转当前节点的指向。
  4. prev 移动到 curr,然后将 curr 移动到 next,继续下一次迭代。
  5. currnull 时,链表反转完成,prev 就是新的头节点。

代码实现

class Solution {public ListNode reverseList(ListNode head) {ListNode prev = null;ListNode curr = head;while (curr != null) {ListNode next = curr.next; // 保存下一个节点curr.next = prev; // 反转当前节点的指向prev = curr; // 将 prev 前移curr = next; // 将 curr 前移}return prev; // prev 成为新链表的头节点}
}

例子演示

输入head = [1,2,3,4,5]

  1. 初始状态:

    prev = null
    curr = 1 -> 2 -> 3 -> 4 -> 5
    
  2. 第一步:

    next = 2 -> 3 -> 4 -> 5
    curr.next = prev  // 1 -> null
    prev = 1 -> null
    curr = 2 -> 3 -> 4 -> 5
    
  3. 第二步:

    next = 3 -> 4 -> 5
    curr.next = prev  // 2 -> 1 -> null
    prev = 2 -> 1 -> null
    curr = 3 -> 4 -> 5
    
  4. 第三步:

    next = 4 -> 5
    curr.next = prev  // 3 -> 2 -> 1 -> null
    prev = 3 -> 2 -> 1 -> null
    curr = 4 -> 5
    
  5. 第四步:

    next = 5
    curr.next = prev  // 4 -> 3 -> 2 -> 1 -> null
    prev = 4 -> 3 -> 2 -> 1 -> null
    curr = 5
    
  6. 第五步:

    next = null
    curr.next = prev  // 5 -> 4 -> 3 -> 2 -> 1 -> null
    prev = 5 -> 4 -> 3 -> 2 -> 1 -> null
    curr = null
    

输出[5, 4, 3, 2, 1]

复杂度分析

  • 时间复杂度:O(n),其中 n 是链表的节点数。我们只遍历了链表一次。
  • 空间复杂度:O(1),只用了常数级别的额外空间。

方法二:递归法

思路

  • 我们递归地反转链表的后续部分,直到最后一个节点成为新的头节点。
  • 每次递归返回时,将当前节点的下一个节点的 next 指向自己,同时将自己的 next 置为空,完成反转。

递归步骤

  1. 如果 headnull 或者 head.nextnull,直接返回 head 作为新的头节点(即递归的终止条件)。
  2. 递归反转剩余的链表。
  3. 将当前节点的下一个节点的 next 指向自己,同时将自己的 next 置为空。
  4. 返回新的头节点。

代码实现

class Solution {public ListNode reverseList(ListNode head) {if (head == null || head.next == null) return head; // 递归终止条件ListNode newHead = reverseList(head.next); // 反转后续链表head.next.next = head; // 将后面的节点指向自己head.next = null; // 断开当前节点与后续的连接return newHead; // 返回新的头节点}
}

例子演示

输入head = [1,2,3,4,5]

  1. 初始递归:

    • reverseList(1) 递归调用 reverseList(2)
  2. 递归到最后一个节点:

    • reverseList(5) 返回 5 作为新头节点。
  3. 逐步反转链表:

    • reverseList(4)

      head = 4 -> 5
      反转后 5 -> 4
      head.next.next = 4
      head.next = null // 4 -> null
      返回 5 -> 4 -> null
      
    • reverseList(3)

      head = 3 -> 4 -> null
      反转后 5 -> 4 -> 3
      head.next.next = 3
      head.next = null
      返回 5 -> 4 -> 3 -> null
      
    • reverseList(2)

      head = 2 -> 3 -> null
      反转后 5 -> 4 -> 3 -> 2
      head.next.next = 2
      head.next = null
      返回 5 -> 4 -> 3 -> 2 -> null
      
    • reverseList(1)

      head = 1 -> 2 -> null
      反转后 5 -> 4 -> 3 -> 2 -> 1
      head.next.next = 1
      head.next = null
      返回 5 -> 4 -> 3 -> 2 -> 1 -> null
      

输出[5, 4, 3, 2, 1]

复杂度分析

  • 时间复杂度:O(n),其中 n 是链表的节点数。递归过程中每个节点只处理一次。
  • 空间复杂度:O(n),递归调用的栈深度为 n

总结:

  • 迭代法:通过三个指针逐步反转链表,时间和空间复杂度都为 O(n) 和 O(1),适合在空间要求较严格的场景下使用。
  • 递归法:利用函数调用栈进行递归,代码简洁直观,但需要 O(n) 的额外空间。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/794974.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

字符串类

常用类String基础知识String类的特性String类是一个final类,不能被继承 String类底层是一个final修饰的字符数组,表示不可变的字符序列(final char value[ ]) String的不可变性:当String值改变时,会在常量池中创建新的字符串字符串-创建字面量方式创建 String s1="a…

AI答案之书解来为你解决难题

本文由 ChatMoney团队出品介绍说明 “答案之书智能体”是您贴心的智慧伙伴,随时准备为您解答生活中的种种困惑。无论您在工作中遭遇瓶颈,还是在情感世界里迷失方向,亦或是对个人成长感到迷茫,它都能倾听您的心声,并给予准确且富有启发的回应。 它并非简单地给出答案,而是…

解锁生活密码,AI答案之书解决复杂难题

本文由 ChatMoney团队出品介绍说明 “答案之书智能体”是您贴心的智慧伙伴,随时准备为您解答生活中的种种困惑。无论您在工作中遭遇瓶颈,还是在情感世界里迷失方向,亦或是对个人成长感到迷茫,它都能倾听您的心声,并给予准确且富有启发的回应。 它并非简单地给出答案,而是…

STM32F7外设FMC控制LCD显示屏

STM32F7外设FMC控制LCD显示屏, 显示屏的点阵LCD控制器(Dot Matrix LCD Controller/Driver)是ST7066U。 配置 在CubeMX中选择图 1 根据实际情况选择,Bank几,LCD片选引脚。图 2 FMC原理 对于FMC如何控制LCD,我的理解: FMC能自动发送数据读写RAM,通过FMC读写LCD的显存就可以…

推荐一款好用的golang修复无效json的库:JSONRepair

简单来说,就是可以将错误格式(非标准)的json修正,如下图所示: 我的json明显不是标准的json格式,是不能被解析的: 但是JSONRepair库也能修复。github地址:https://github.com/kaptinlin/jsonrepair 使用也非常简单: 1、安装:go get github.com/kaptinlin/jsonrepair2、…

全志T507-H国产平台Ubuntu系统正式发布,让您的应用开发更便捷!

为了满足广大工业用户的需求,创龙科技针对全志T507-H工业平台进行了Ubuntu系统适配,开发环境如下: Ubuntu:Ubuntu18.04.4 U-Boot:U-Boot-2018.05 Kernel:Linux-4.9.170、Linux-RT-4.9.170 LinuxSDK:LinuxSDK-[版本号].tar.gz (基于全志官方V2.0_20220618)全志T507-H国…

IEC103设备数据 转 IEC61850项目案例

目录 1 案例说明 1 2 VFBOX网关工作原理 1 3 准备工作 2 4 配置VFBOX网关采集103设备数是 2 5 用IEC61850协议转发数据 4 6 网关使用多个逻辑设备和逻辑节点的方法 6 7 IEC103协议说明 8 8 案例总结 9 1 案例说明设置网关采集IEC103设备数据 把采集的数据转成IEC61850协议转发给…

【触想智能】工业一体机在物流领域上的四大应用分析

随着物流业的快速发展,工业一体机在物流领域上的应用越来越普遍。工业一体机是一种高级智能设备,是多种技术的综合应用,包括机械、电子、计算机、通讯等。在物流行业中,工业一体机可以发挥其先进的技术和功能,提高物流的效率和质量。本文将探讨工业一体机在物流领域上的应…

使用 nuxi upgrade 升级现有nuxt项目版本

title: 使用 nuxi upgrade 升级现有nuxt项目版本 date: 2024/9/10 updated: 2024/9/10 author: cmdragon excerpt: 摘要:本文介绍了如何使用nuxi upgrade命令升级Nuxt 3项目,包括打开终端、运行升级命令、使用选项、测试项目等步骤,以及升级前的注意事项,如备份代码、检查…

[MySQL]为什么主键最好是有序递增的

为什么主键索引最好是有序递增的我们在建表的时候,都会默认将主键索引设置为自增的,具体为什么要这样做呢?又什么好处? InnoDB 创建主键索引默认为聚簇索引,数据被存放在了 B+Tree 的叶子节点上。也就是说,同一个叶子节点内的各个数据是按主键顺序存放的,因此,每当有一…