[牛客top101]详解01,02,反转链表问题

news2025/2/4 6:44:13

文章目录

  • 前言
  • 1. 整体翻转链表
    • 1.1 题目描述
    • 1.2 题目详解
  • 2. 翻转链表的部分区间
    • 2.1 题目描述
    • 2.2 题目详解
  • 3. 完整代码展示


前言

从本章开始,我们就开始刷题旅程啦,路上必定问题多多,但还是得练呐!所以,就现在,开始啦!


1. 整体翻转链表

1.1 题目描述

给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。

数据范围: 0\leq n\leq10000≤n≤1000
要求:空间复杂度 O(1)O(1) ,时间复杂度 O(n)O(n) 。

如当输入链表{1,2,3}时,
经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。
以上转换过程如下图所示:
在这里插入图片描述

1.2 题目详解

首先呢,我们的思路肯定是要遍历一遍链表,第一个节点指向空,之后把每个链表的next指向前一个节点,那么链表就翻转完成了.所以,我们会用到一个循环.循环的终止条件我们一会再考虑.
怎么具体实现这个过程呢?
假如我们这样将第一个节点的next设置为null

ListNode cur = head;
cur.next = null

会发现,我们丢失了原本head的next,循环也没法继续.所以呢,在改变每个节点的next值之前,我们需要先把节点原来的next值保存下来
例如这样改变第一个节点

ListNode cur = head;
ListNode curNext = cur.next;
cur.next = null
cur = curNext;

那么,怎么将第二个节点的next改成第一个节点呢.
首先,我们肯定是需要将改变第一个节点时就要把它保存下来,
ListNode preCur = cur;但是每次循环,上一次循环中的内容不会被保留,所以,这里,我们要在循环外定义preCur.之后改变第二个节点,cur.next = preCur,就完成第二个节点了.
因为直到最后一个节点,最后一个节点也会进行同样操作,所以,循环结束的条件是(cur != null),不能是(cur.next != null)
综上所述,我们得到循环

public ListNode ReverseList(ListNode head) {
        //找到后一个节点,它的next是preNode,直到node == null
       ListNode  preCur = null;
       ListNode cur = head;
       while(cur != null){
           //因为会改变cur.next,所以,事先要把cur.next存好
           ListNode curNext = cur.next;
           cur.next = preCur;
           //记录下前面的节点,因为循环会刷新数据,所以把pre定义到外面
           preCur = cur;
           cur = curNext;
       }

最后,返回值是啥捏,我们要返回新链表的头结点,也就是返回preCur.

2. 翻转链表的部分区间

2.1 题目描述

将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度 O(n)O(n),空间复杂度 O(1)O(1)。
例如:
给出的链表为 1\to 2 \to 3 \to 4 \to 5 \to NULL1→2→3→4→5→NULL, m=2,n=4m=2,n=4,
返回 1\to 4\to 3\to 2\to 5\to NULL1→4→3→2→5→NULL.

数据范围: 链表长度 0 < size \le 10000<size≤1000,0 < m \le n \le size0<m≤n≤size,链表中每个节点的值满足 |val| \le 1000∣val∣≤1000
要求:时间复杂度 O(n)O(n) ,空间复杂度 O(n)O(n)
进阶:时间复杂度 O(n)O(n),空间复杂度 O(1)O(1)

在这里插入图片描述
如下图,翻转链表的2~4(图省事,没画上链子)
在这里插入图片描述

2.2 题目详解

这里呢,我们会想到遍历链表,先把指定区间里的节点存起来,都存进去之后,再倒着拿出来,连到区间前的节点后面.说到正着存进去,倒着拿出来,我们很容易就想到了栈,对喽,就是用栈存区间里的节点.
注意这里,得定义一个pre记着从哪之后开始存的,要不,从栈里拿出来的节点不知道连谁的后面.

    	int i = 1;
        ListNode pre = null;
        while(i < m){
            pre = cur;
            cur = cur.next;
            i++;
        }
        //把stack里的节点连到pre后面
        Stack<ListNode> stack = new Stack<>();
        while(i <= n){
            stack.push(cur);
            cur = cur.next;
            i++;
        }

之后,就可以从栈里拿出节点,连在pre节点后面啦.这里我们要注意一个点,如果区间是从1开始的,就意味着pre为null,在连到pre后面之前,要改一下pre的值.另外,链表的头头也被动了,要想想怎么找链表的头结点.如下图
在这里插入图片描述
头结点变成了stack.pop();
代码如下

		if(pre == null){
            pre = stack.pop();
            head = pre;
             while(!stack.isEmpty()){
                ListNode top = stack.pop();
                pre.next = top;
                pre = top;
            }
            pre.next = cur;
            return head;  
        }

那pre不为null时,就正常往pre后面放就可,如下

		if(pre == null){
            pre = stack.pop();
            head = pre;
             while(!stack.isEmpty()){
                ListNode top = stack.pop();
                pre.next = top;
                pre = top;
            }
            pre.next = cur;
            return head;  
        }else{
            while(!stack.isEmpty()){
                ListNode top = stack.pop();
                pre.next = top;
                pre = pre.next;
            }
        }

最后呢,要改一下最后一个被弹出的节点的next值,看看之前,在进站的时候,cur正好走到指定区间的后面,这里直接接上cur就可以.

pre.next = cur;

3. 完整代码展示

完整代码如下

public ListNode ReverseList(ListNode head) {
        //找到后一个节点,它的next是preNode,直到node == null
        if(head == null){
            return head;
        }
        ListNode preCur = null;
        ListNode cur = head;
       while(cur != null){
           //因为会改变cur.next,所以,事先要把cur.next存好
           ListNode curNext = cur.next;
           cur.next = preCur;
           //记录下前面的节点,因为循环会刷新数据,所以把pre定义到外面
           preCur = cur;
           cur = curNext;
       }
       return preCur;
    }
	public ListNode reverseBetween (ListNode head, int m, int n) {
        //区间反转,
        ListNode cur = head;
        if(head == null){
            return null;
        }
        int i = 1;
        ListNode pre = null;
        while(i < m){
            pre = cur;
            cur = cur.next;
            i++;
        }
        //把stack里的节点连到pre后面
        Stack<ListNode> stack = new Stack<>();
        while(i <= n){
            stack.push(cur);
            cur = cur.next;
            i++;
        }
        if(pre == null){
            pre = stack.pop();
            head = pre;
             while(!stack.isEmpty()){
                ListNode top = stack.pop();
                pre.next = top;
                pre = top;
            }
            pre.next = cur;
            return head;  
        }else{
            while(!stack.isEmpty()){
                ListNode top = stack.pop();
                pre.next = top;
                pre = pre.next;
            }
        }
        //加进来了,之后开始弹出元素,连到pre后面
    
        pre.next = cur;
        return head;
    }


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(续)SSM整合之springmvc笔记(拦截器)(P164-168)

目录 一 准备工作 1. 创建spring_mvc_extension com.atguigu 2 .导入依赖 3. 添加web模块 4 .web.xml 5 . springmvc.xml 6 index.html 7 控制层 8 success.html 9 .添加到tomcat ​10 测试 二 . 测试拦截器 1 . index.html 2 . FirstInterceptor …

Docker概念及安装

一、Docker概述 1 IT架构的演进&#xff1a; 裸金属 → 虚拟机 → 容器→ 函数化、代码化 云计算涌现出很多改变传统IT架构和运维方式的新技术&#xff0c;比如虚拟机、容器、微服务、Serverless&#xff08;无服务&#xff09;&#xff0c;无论这些技术应用在哪些场景&…

智慧能源解决方案-最新全套文件

智慧能源解决方案-最新全套文件一、建设背景存在的问题二、建设架构三、建设方案四、获取 - 智慧能源全套最新解决方案合集一、建设背景 我国工业能耗占全国总能耗比例近70%&#xff0c;许多经济大省工业能耗占比甚至显著高于70%&#xff0c;工业企业能耗增速也明显领先全国其…

Bash脚本debug攻略

初学Bash时, 我从未想过去debug Bash脚本, 也从未想过Bash脚本也能debug. 随着技术的增长, 写的脚本越来越复杂, 使用echo打印日志来调试脚本的方式也越来越捉襟见肘了. 直到某天 通读了一遍Bash Reference Manual, 才发现Bash脚本也是可以debug的. 下面就介绍三种debug Bash脚…

定时器之编码器模式

1.什么是编码器 编码器&#xff08;encoder&#xff09;是将信号或数据进行编制、转换为可用以通讯、传输和存储的信号形式的设备。编码器把角位移或直线位移转换成电信号&#xff0c;前者称为码盘&#xff0c;后者称为码尺。 2.分类 按照读出方式编码器可以分为接触式和非接…

C++学习笔记(面向对象部分开始6500字复习总结)

函数重载 1.对象属性 对象方法 和 类属性 类方法 2.const函数read only&#xff0c;不会修改任何数据 3.class默认private&#xff0c;struct默认public 4.&#xff01;&#xff01;&#xff01;&#xff01;C编译器优化&#xff01;&#xff01;&#xff01;《个人理解》当…

单细胞分析:数据整合(九)

导读 本文将学习跨条件执行单细胞整合&#xff0c;以识别彼此相似的细胞。 1. 目标 跨条件对齐相同的细胞类型。2. 挑战 对齐相似细胞类型的细胞&#xff0c;这样就不会因为样本、条件、模式或批次之间的差异而在后续分析中进行聚类。 3. 推荐 建议先不整合分析&#xff0c;再决…

2020下半年软件设计师上午题错题总结

2020下半年 1、以下关于两个浮点数相加运算的叙述中&#xff0c;正确的是 &#xff08;3&#xff09; 。 A. 首先进行对阶&#xff0c;阶码大的向阶码小的对齐 B. 首先进行对阶&#xff0c;阶码小的向阶码大的对齐 C. 不需要对阶&#xff0c;直接将尾数相加 D. 不需要对阶…

[附源码]java毕业设计网上购物商城

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

33.nacos客户端读取多配置文件实例(springcloud)

1.配置文件的读取方式【重点】nacos 配置中心通过 namespace、dataId 和 group 来唯一确定一条配置。 Namespace&#xff1a;即命名空间。默认的命名空间为 public&#xff0c;我们可以在 Nacos 控制台中新建命名空间&#xff1b;dataId&#xff1a;即配置文件名称 Group &…

比 O(nlog(n)) 做得更好——创造合适的条件

我们可以比 O(nlog(n)) 更快地排序。 长按关注《Python学研大本营》&#xff0c;加入读者群&#xff0c;分享更多精彩 扫码关注《Python学研大本营》&#xff0c;加入读者群&#xff0c;分享更多精彩 介绍 我将介绍一种我称之为 groupSort 的排序方法。我没有直接解决排序问题…

基于小波变换编码的纹理图像分割

目录 1.算法概述 2.仿真效果预览 3.MATLAB部分代码预览 4.完整MATLAB程序 1.算法概述 我们使用11或13维特征向量表示图像中的每个像素。两个特征用于表示像素之间的空间关系&#xff1b;由图像尺寸规格化的x和y像素坐标。对于灰度图像&#xff0c;一个特征是低通表示&#…

Python编程从入门到实践 第十一章:测试代码 练习答案记录

Python编程从入门到实践 第十一章&#xff1a;测试代码 练习答案记录 练习题导航Python编程从入门到实践 第十一章&#xff1a;测试代码 练习答案记录11.1 测试函数11.1.1 单元测试和测试用例11.1.2 可通过的测试11.1.3 未通过的测试11.1.4 测试未通过时怎么办11.1.5 添加新测试…

Flutter/Dart 中的 extension 方法

Flutter Dart 中的 extension 方法 前言 我们将讨论 extension 方法如何对我们有用&#xff0c;以及为什么您的代码因为它们而变得更加精确和可读的原因。 简介 在本文中&#xff0c;我们将学习 Dart 中的 extension 方法。也许你想知道那是什么&#xff0c;它是如何工作的&…

HIve数仓新零售项目DWS层的构建(Full join)模型

HIve数仓新零售项目 注&#xff1a;大家觉得博客好的话&#xff0c;别忘了点赞收藏呀&#xff0c;本人每周都会更新关于人工智能和大数据相关的内容&#xff0c;内容多为原创&#xff0c;Python Java Scala SQL 代码&#xff0c;CV NLP 推荐系统等&#xff0c;Spark Flink Kaf…

全自动调节灯光强度的实现(仿真+程序+文档)

目 录 摘 要 I Abstract II 绪论 1 1.1 选题背景及意义 1 1.2 国内外研究现状 1 1.3 研究主要内容 3图书馆学习桌台灯智能控制系统简介与方案分析 4 2.1 大学图书馆照明控制现状 4 2.2 图书馆学习桌台灯智能控制系统简介 4 2.3 系统控制方案分析 4 2.4 本章小节 5系统硬件设计…

JavaScript练手小技巧:我破解了原神官网全屏滚动的秘密

这个标题有点夺人眼球&#xff0c;哈啊哈~骗点击率的。 “原神”官网当真的做的很漂亮&#xff0c;虽然我没玩过这个游戏&#xff0c;但是禁不住喜欢这个网站啊。 https://ys.mihoyo.com/ 最近居家教学上网课。除了上课&#xff0c;实在不想做学校安排的其它任务&#xff0c…

热量衡算习题课

第一部分 --- 传热计算综合例题 1.qm是质量流量&#xff0c;T1&#xff0c;2和 t1,2对应的是热流体和冷流体分别在管道进口和出口的温度 2.吊塔tm是传热温差 3.α1是热流体的对流传热系数&#xff0c;α2是冷流体的对流传热系数&#xff0c;K是整个对流传热过程的总的传热系…

【Linux】在Xilinx平台上实现UVC Gadget(2)- 解决dwc3驱动bug

【Linux】在Xilinx平台上实现UVC Gadget&#xff08;2&#xff09;- 解决dwc3驱动bug一、bug描述二、具体修改方法1. 找到内核源码位置并复制到其他目录2. Petalinux里面设置使用自定义内核源码1) 选第2个Linux Components Selection2) 选linux-kernel&#xff0c;回车&#xf…

【笔试题】【day22】

文章目录第一题&#xff08;循环队列的元素个数&#xff09;第二题&#xff08;二叉排序树插入规则&#xff09;第三题&#xff08;线性探测的平均查找长度&#xff09;第四题&#xff08;关键字比较次数与初始序列无关的&#xff09;第一题&#xff08;循环队列的元素个数&…