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

链表题目总结 -- 递归

目录

  • 一. 递归反转整个链表
    • 1. 思路简述
    • 2. 代码
    • 3. 总结
  • 二. 反转链表前 N 个节点
    • 1. 思路简述
    • 2. 代码
    • 3. 总结
  • 三、反转链表的一部分
    • 1. 思路简述
    • 2. 代码
    • 3.总结
  • 四、从节点M开始反转后面的链表
    • 1. 思路简述
    • 2. 代码
    • 3.总结

一. 递归反转整个链表

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

1. 思路简述

  • 所谓递归,就像那句歌词一样“一层一层剥开我的心”,我们从第一个节点一直向下探索,发现节点5。现在想:如果是单个节点,那反转链表其实就相当于自身本身,也就是不用动了。这里考虑一个临界情况,如果传进的参数(head指针)是null,那也不用动了,直接返回其本身就可以。
  • 来到倒数第二层,也就是节点4,现在情况变成了节点有2个的链表,现在需要反转,那么我们只需要将中间的指针做一个反转就好了,而当前传进来的指针(head),其实是节点4的head指针,那么就有head.next.next = head;,最后将节点4的后继赋值为空(head.next = null),这表示这一阶段(有2个节点的链表已经反转完成。如果链表只有两个节点,直接输出就可以。)
  • 重复上面步骤,直到最后整个链表都反转了
    在这里插入图片描述

2. 代码

/*** Definition for singly-linked list.* public class ListNode {*     int val;*     ListNode next;*     ListNode() {}*     ListNode(int val) { this.val = val; }*     ListNode(int val, ListNode next) { this.val = val; this.next = next; }* }*/
class Solution {                       public ListNode reverseList(ListNode head) {//从后向前,一点点的进行反转//先分析特殊情况,链表有一个节点或者没有节点,直接返回头结点if(head == null || head.next == null)return head;else{//last为反转链表之后的头指针ListNode last = reverseList(head.next);head.next.next = head;head.next = null;return last;}}
}

3. 总结

  • 时间复杂度:o(n)
  • 空间复杂度:o(n),需要用栈
  • 第一次做的时候,还以为是逆向输出,整了半天,搞错了。
  • 对递归的边界条件掌握的还是不好,像head == null这一块,博主当时就没想到与head.next进行合并。
  • head.next = null;一定要注意,否则,会出现成环的现象

二. 反转链表前 N 个节点

  • 题目链接:没有链接,给一个函数名:public static ListNode reverseN(ListNode head,int n);,自己去练吧。

1. 思路简述

  • 本质和反转链表差不多,只是在边界值的地方需要注意,

2. 代码

		//存放需要逆转链表的后继第一个节点public static ListNode successor = null;public static ListNode reverseN(ListNode head,int n){//逆转前n个节点if (n == 1) {successor = head.next;return head;}//递归,将下一个节点放进去ListNode last = reverseN(head.next, n - 1);head.next.next = head;head.next = successor;return last;}

3. 总结

  • 也就是反转链表,只是每次反转完,head后面要接后继节点(后面的一段不需要反转的链表),就变了这一点。
  • 时间复杂度:o(n)
  • 空间复杂度:o(n),需要用栈

三、反转链表的一部分

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

1. 思路简述

  • 将问题转换成反转前n个节点的问题。

2. 代码

	//存放需要逆转链表的后继第一个节点public static ListNode successor = null;public static ListNode reverseN(ListNode head,int n){//逆转前n个节点if (n == 1) {successor = head.next;return head;}//递归,将下一个节点放进去ListNode last = reverseN(head.next, n - 1);head.next.next = head;head.next = successor;return last;}ListNode reverseBetween(ListNode head, int m, int n) {// 当m为1的时候,装换成了反转前面几个节点的链表的问题if (m == 1) {return reverseN(head, n);}// 将前面不需要反转的链表和后面反转过的链表接在一起head.next = reverseBetween(head.next, m - 1, n - 1);return head;}

3.总结

  • head.next = reverseBetween(head.next, m - 1, n - 1); 为什么是head.next呢,看边界情况,m = 1时,返回的是后面已经反转过的链表,也就是说前面的链表压根不需要反转,只要把它们拼接在一起就行了。
  • 再说为什么是m - 1的问题,每递归一次,新链表就会从前面缩短一节,那么对于新链表来说,就是从第m-1个节点开始反转,到第n - 1个节点结束反转。这里的关键是链表从头开始缩短了,所以,m - 1 和 n - 1都要存在。

四、从节点M开始反转后面的链表

  • 题目链接:没有链接,给一个函数名:public static ListNode reverseP(ListNode head,int m);,自己去练吧。

1. 思路简述

  • 转换成反转单链表的问题

2. 代码

    public ListNode reverseList(ListNode head) {//从后向前,一点点的进行反转//先分析特殊情况,链表有一个节点或者没有节点,直接返回头结点if(head == null || head.next == null)return head;else{//last为反转链表之后的头指针ListNode last = reverseList(head.next);head.next.next = head;head.next = null;return last;}}public static ListNode reverseP(ListNode head, int m){//转换成反转链表的问题if(m == 1){return reverseList(head);}head.next = reverseP(head.next, m - 1);return head;}

3.总结

  • 和上一题差不多,一直递归,到链表需要反转的地方(m == 1),开始反转整个单链表。

参考:https://labuladong.github.io/algo/di-yi-zhan-da78c/shou-ba-sh-8f30d/di-gui-mo–10b77/

相关文章:

链表题目总结 -- 递归

目录一. 递归反转整个链表1. 思路简述2. 代码3. 总结二. 反转链表前 N 个节点1. 思路简述2. 代码3. 总结三、反转链表的一部分1. 思路简述2. 代码3.总结四、从节点M开始反转后面的链表1. 思路简述2. 代码3.总结一. 递归反转整个链表 题目链接:https://leetcode.cn/…...

重写-linux内存管理-伙伴分配器(一)

文章目录一、伙伴系统的结构二、初始化三、分配内存3.1 prepare_alloc_pages3.2 get_page_from_freelist3.2.1 zone_watermark_fast3.2.2 zone_watermark_ok3.2.3 rmqueue3.2.3.1 rmqueue_pcplist3.2.3.2 __rmqueue3.2.3.2.1 __rmqueue_smallest3.2.3.2.2 __rmqueue_fallback3.…...

为什么要用springboot进行开发呢?

文章目录前言1、那么Springboot是怎么实现自动配置的1.1 启动类1.2 SpringBootApplication1.3 Configuration1.4 ComponentScan1.5 EnableAutoConfiguration1.6 两个重要注解1.7 AutoConfigurationPackage注解1.8 Import(AutoConfigurationImportSelector.class)注解1.9自动配置…...

设备树信息解析相关函数

一。可以通过三种不同的方式解析设备树节点: 1.根据设备树节点的名字解析设备树节点 struct device_node *of_find_node_by_name(struct device_node *from, const char *name); 参数: from:当前节点父节点首地址 name:设备树节点名字 …...

LeetCode-1124. 表现良好的最长时间段【哈希表,前缀和,单调栈】

LeetCode-1124. 表现良好的最长时间段【哈希表,前缀和,单调栈】题目描述:解题思路一:查字典。cur是当前的前缀和(劳累与不劳累天数之差),向前遍历。有两种情况。情况一,若cur大于0则是[0,i]的劳累与不劳累天…...

vue-router路由配置

介绍:路由配置主要是用来确定网站访问路径对应哪个文件代码显示的,这里主要描述路由的配置、子路由、动态路由(运行中添加删除路由) 1、npm添加 npm install vue-router // 执行完后会自动在package.json中添加 "vue-router…...

中国计算机设计大赛来啦!用飞桨驱动智慧救援机器狗

‍‍中国大学生计算机设计大赛是我国高校面向本科生最早的赛事之一,自2008年开赛至今,一直由教育部高校与计算机相关教指委等或独立或联合主办。大赛的目的是以赛促学、以赛促教、以赛促创,为国家培养德智体美劳全面发展的创新型、复合型、应…...

嘉定区2022年高新技术企业认定资助申报指南

各镇人民政府,街道办事处,嘉定工业区、菊园新区管委会,各相关企业: 为推进实施创新驱动发展战略,加快建设具有全球影响力的科技创新中心,根据《嘉定区关于加快本区高新技术企业发展的实施方案(…...

【C++】关键字、命名空间、输入和输出、缺省参数、函数重载

C关键字(C98)命名空间产生背景命名空间定义命名空间使用输入&输出缺省参数什么叫缺省参数缺省参数分类函数重载函数重载概念C支持函数重载的原理--名字修饰C关键字(C98) C总计63个关键字,C语言32个关键字。 下面我们先看一下C有多少关键字,不对关键…...

【一道面试题】关于HashMap的一系列问题

HashMap底层数据结构在1.7与1.8的变化 1.7是基于数组链表实现的,1.8是基于数组链表红黑树实现的,链表长度达到8时会树化 使用哈希表的好处 使用hash表是为了提升查找效率,比如我现在要在数组中查找一个A对象,在这种情况下是无法…...

论文笔记: Monocular Depth Estimation: a Review of the 2022 State of the Art

中文标题:单目深度估计:回顾2022年最先进技术 本文对比了物种最近的基于深度学习的单目深度估计方法: GPLDepth(2022)[15]: Global-Local Path Networks for Monocular Depth Estimation with Vertical CutDepthAdabins(2021)[1]: Adabins:…...

Springmvc补充配置

Controller配置总结 控制器通常通过接口定义或注解定义两种方法实现 在用接口定义写控制器时&#xff0c;需要去Spring配置文件中注册请求的bean;name对应请求路径&#xff0c;class对应处理请求的类。 <bean id"/hello" class"com.demo.Controller.HelloCo…...

MySQL 的 datetime等日期和时间处理SQL函数及格式化显示

MySQL 的 datetime等日期和时间处理SQL函数及格式化显示MySQL 时间相关的SQL函数&#xff1a;MySQL的SQL DATE_FORMAT函数&#xff1a;用于以不同的格式显示日期/时间数据。DATE_FORMAT(date, format) 根据格式串 format 格式化日期或日期和时间值 date&#xff0c;返回结果串。…...

基于微信云开发的防诈反诈宣传教育答题小程序

基于微信云开发的防诈反诈宣传教育答题小程序一、前言介绍作为当代大学生&#xff0c;诈骗事件的发生屡见不鲜&#xff0c;但却未能引起大家的重视。高校以线上宣传、阵地展示为主&#xff0c;线下学习、实地送法为辅&#xff0c;从而构筑立体化反诈骗防线。在线答题考试是一种…...

Map和Set

Map和set是一种专门用来进行搜索的容器或者数据结构&#xff0c;其搜索的效率与其具体的实例化子类有关。数据的一般查找方式有两种&#xff1a;直接遍历和二分查找。但这两种查找方式都有很大的局限性&#xff0c;也不便于对数据进行增删查改等操作。对于这一类数据的查找&…...

【位运算问题】Leetcode 136、137、260问题详解及代码实现

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法......感兴趣就关注我吧&#xff01;你定不会失望。 &#x1f308;个人主页&#xff1a;主页链接 &#x1f308;算法专栏&#xff1a;专栏链接 我会一直往里填充内容哒&#xff01; &…...

同花顺2023届春招内推

同花顺2023届春招开始啦&#xff01; 同花顺是国内首家上市的互联网金融信息服务平台&#xff0c;如果你对互联网金融感兴趣&#xff0c;如果你有志向在人工智能方向发挥所长&#xff0c;如果你也是一个激情澎湃的小伙伴&#xff0c;欢迎加入我们&#xff01;岗位类别&#xf…...

深入Kafka核心设计与实践原理读书笔记第三章消费者

消费者 消费者与消费组 消费者Consumer负责定于kafka中的主题Topic&#xff0c;并且从订阅的主题上拉取消息。与其他消息中间件不同的在于它有一个消费组。每个消费者对应一个消费组&#xff0c;当消息发布到主题后&#xff0c;只会被投递给订阅它的消费组的一个消费者。 如…...

IDEA 中使用 Git 图文教程详解

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

【Linux系统】进程概念

目录 1 冯诺依曼体系结构 2 操作系统(Operator System) 概念 设计OS的目的 定位 总结 系统调用和库函数概念 3 进程 3.1 基本概念 3.2 描述进程-PCB 3.2 组织进程 3.3 查看进程 3.4 通过系统调用获取进程标示符 3.5 进程状态 在了解进程概念前我们还得了解下冯诺…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

重启Eureka集群中的节点,对已经注册的服务有什么影响

先看答案&#xff0c;如果正确地操作&#xff0c;重启Eureka集群中的节点&#xff0c;对已经注册的服务影响非常小&#xff0c;甚至可以做到无感知。 但如果操作不当&#xff0c;可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...