数据结构(Java版)第八期:LinkedList与链表(三)

专栏:数据结构(Java版)
个人主页:手握风云
目录
一、链表中的经典面试题
1.1. 链表分割
1.2. 链表的回文结构
1.3. 相交链表
1.4. 环形链表
一、链表中的经典面试题
1.1. 链表分割

题目中要求不能改变原来的数据顺序,也就是如上图所示。我们先定义一个cur引用去遍历这个链表,用每个结点的val值与x进行比较,然后利用尾插的方法把结点插入进两个链表中。我们先定义bs、be、as、ae四个引用来表示两个链表的头尾,在尾插的时候需要注意,利用ae.next = node;ae = node,记录下尾结点,保证ae永远指向最后一个结点,同时be.next=as,连接上两个链表。
class ListNode{int val;ListNode next = null;public ListNode(int val) {this.val = val;}
}public class Partition {public ListNode partition(ListNode pHead, int x){ListNode bs = null;ListNode be = null;ListNode as = null;ListNode ae = null;ListNode cur = pHead;while(cur != null){if(cur.val < x){}else{}}}
}
代码的大体框架已经写好,这时我们需要考虑一下当第一段插入第一个节点时,第一个节点既是头又是尾。这时有需要分两种情况,第一次插入与下一次插入,来移动be引用。
while(cur != null){if(cur.val < x){//第一次插入if(bs == null){be = bs = cur;}else {be.next = cur;be = cur;}}else{//第一次插入if(as == null){ae = as = cur;}else {ae.next = cur;ae = cur;}}cur = cur.next;
这时的代码还存在一种我们没有想到的情况,如果给定的测试用例都大于x的值呢。这是我们就需要返回as。我们还需要分情况。
if(bs == null){return as;}
如果这是我们放到OJ进行测试,发现报出异常。

这个异常的原因比较隐蔽。因为bs为空,尾节点ae会返回bs,如果ae之前的地址指向之前的某个节点,就会造成链表的死循环,此时我们要将排列之后的链表最后一个节点手动置为null。
完整代码:
class ListNode{int val;ListNode next = null;public ListNode(int val) {this.val = val;}
}public class Partition {public ListNode partition(ListNode pHead, int x){ListNode bs = null;ListNode be = null;ListNode as = null;ListNode ae = null;ListNode cur = pHead;while(cur != null){if(cur.val < x){//第一次插入if(bs == null){be = bs = cur;}else {be.next = cur;be = cur;}}else{//第一次插入if(as == null){ae = as = cur;}else {ae.next = cur;ae = cur;}}cur = cur.next;}if(bs == null){return as;}be.next = as;//连接上两个链表if(as != null){ae.next = null;}return bs;}
}
1.2. 链表的回文结构
第一种思路,我们可以使用双引用算法,一个left引用从左开始向右移动,另一个right引用从右开始向左移动。但由于这个链表是单链表,只能从一个方向遍历。
第二种思路,把链表里的val值取出,存进一个数组中,但题目要求空间复杂度为 。
第三种思路,翻转一半的链表。过程分为三步,第一步,找到链表的中间部分;第二步,将链表的一半进行翻转。我们在上一期中,已经实现了翻转链表和寻找链表的中间节点。

while(cur != null){curN = cur.next;cur.next = slow;slow = cur;cur = curN;
}
利用上面的代码我们就可以来翻转链表,第三步,head从前往后,slow从后往前,比较head.val是否与slow.val相等,直到slow引用与头节点相遇为止。这里我们讨论的是奇数个节点的链表,如果是有偶数个节点的链表,那么fast为空。
当链表的节点为偶数时,我们不能按照之前的做法,当head.next = slow时,直接返回true。

完整代码:
import java.util.Scanner;class ListNode{int val;ListNode next;public ListNode(int val) {this.val = val;}
}public class PalindromeList {public boolean chkPalindrome(ListNode A){//1、找到链表的中间节点ListNode fast = A;ListNode slow = A;while(fast != null && fast.next != null){fast = fast.next.next;slow = slow.next;}//2、反转链表ListNode cur = slow.next;while(cur != null){ListNode curN = cur.next;cur.next = slow;slow = cur;cur = curN;}//3、引用A与slow同时移动while(A != slow){if(A.val != slow.val){return false;}//判断偶数个节点情况if(A.next == slow){return true;}A = A.next;slow = slow.next;}return true;}
}
1.3. 相交链表
对于链表相交的问题,我们首先要考虑明白,到底是X形相交,还是Y形相交?


如上图所示,很明显两个链表相交之后呈Y形。要解决问题,我们同样利用双引用的算法。第一步,先求出两个链表的长度len1、len2;第二步求出两个链表的长度差len=len1-len2;第三步,让长的链表先走len步;第四步,headA与headA同时走,相遇之后就是公共交节点。
这个题的思路其实很简单,但是其中也有一些比较麻烦的步骤。在第二步中,如果说len1<len2,那么len<0。第三步中,我们又怎么知道哪个链表更长?
class ListNode{int val;ListNode next;ListNode(int x){val = x;next = null;}
}public class Solution {public ListNode getIntersectionNode(ListNode headA, ListNode headB){ListNode pl = headA;//先假设链表A是长的ListNode ps = headB;//求两个链表的长度int len1 = 0,len2 = 0;while(pl != null){len1++;pl = pl.next;}while(ps != null){len2++;ps = ps.next;}pl = headA;ps = headB;//求链表的长度差int len = len1 - len2;if(len < 0){pl = headB;ps = headA;len = len2-len1;}//让pl先走len步while(len != 0){pl = pl.next;len--;}//pl与ps同时走,知道相遇。while(pl != ps){pl = pl.next;ps = ps.next;}//如果没有公共节点,直接返回nullif(pl == null){return null;}return pl;}
}
1.4. 环形链表
快慢引用,即慢引用⼀次⾛⼀步,快引用⼀次⾛两步,两个引用从链表起始位置开始运⾏,如果链表带环则⼀定会在环中相遇,否则快引用率先⾛到链表的末尾。与现实生活中不同,两人相遇有可能是擦肩而过。而引用确实一步一步走的。


为什么要让快引用走两步,慢引用走一步呢?我们想象一种最极限的情况,当fast刚走完一圈时,slow刚进入环内,两个引用的距离差刚好是一个环的距离。当fast与slow每走一次,它们的距离就越接近一个环。
class ListNode{int val;ListNode next;ListNode(int x){val = x;next = null;}
}public class Solution {public boolean hasCycle(ListNode head){ListNode fast = head;ListNode slow = head;while(fast != null && fast.next != null){fast = fast.next.next;slow = slow.next;if(fast == slow){return true;}}return false;}
}
相关文章:
数据结构(Java版)第八期:LinkedList与链表(三)
专栏:数据结构(Java版) 个人主页:手握风云 目录 一、链表中的经典面试题 1.1. 链表分割 1.2. 链表的回文结构 1.3. 相交链表 1.4. 环形链表 一、链表中的经典面试题 1.1. 链表分割 题目中要求不能改变原来的数据顺序,也就是如上图所示。…...
数据结构学习记录-数据结构概念
1 数据结构: 数据结构是计算机存储,管理数据的方式。 数据必须依据某种逻辑联系组织在一起存储在计算机内 数据结构研究的就是这种数据的存储结构和数据的逻辑结构。 1.1 数据的逻辑结构: 逻辑结构指的是数据本身之间的关系 集合&#x…...
【Linux】11.Linux基础开发工具使用(4)
文章目录 3. Linux调试器-gdb使用3.1 背景3.2 下载安装3.3 使用gdb查询3.4 开始使用 3. Linux调试器-gdb使用 3.1 背景 程序的发布方式有两种,debug模式和release模式 Linux gcc/g出来的二进制程序,默认是release模式 要使用gdb调试,必须…...
数据结构与算法之栈: LeetCode 1047. 删除字符串中的所有相邻重复项 (Ts版)
删除字符串中的所有相邻重复项 https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/ 描述 给出由小写字母组成的字符串 s,重复项删除操作会选择两个相邻且相同的字母,并删除它们在 s 上反复执行重复项删除操作,直到无…...
C++ 在线编译软件介绍、杭电OJ、北大OJ、力扣OJ
在线编译软件的话,可见下: https://www.jyshare.com/compile/12/ 杭州电子科技大学开发的一个免费的写代码地址 ,杭电OJ https://bestcoder.hdu.edu.cn/ 北大OJ http://poj.org/ 力扣OJ 力扣 (LeetCode) 全球极客挚爱的技术成长平台...
Java学习笔记(二十三)
1 CacheEvict CacheEvict是Spring框架中用于清空缓存的注解。以下是对CacheEvict注解的详细介绍: 1.1 作用 CacheEvict注解的主要作用是删除缓存中的数据。在方法执行后或执行前(根据配置),它可以清空指定的缓存项或整个缓存区…...
《AI赋能鸿蒙Next,开启智能关卡设计新时代》
在游戏开发领域,关卡设计是至关重要的一环,它直接影响着玩家的游戏体验和沉浸感。而随着人工智能技术的飞速发展,结合鸿蒙Next系统的强大功能,为游戏的智能关卡设计带来了全新的思路和方法。 利用AI学习玩家行为模式 在鸿蒙Next…...
js:正则表达式
目录 正则表达式的语法 定义 检测 检索 元字符 边界符 量词 字符类 表单判断案例 修饰符 过滤敏感词 正则表达式是一种用于匹配和操作文本的强大工具,它是由一系列字符和特殊字符组成的模式,用于描述要匹配的文本字符组合模式 正则表达式是一…...
linux环境使用docker部署多个war项目
如果你的需求是在一个服务器上部署多个Tomcat项目,并且每个项目需要独立运行,可以通过以下方式实现: 1. 使用不同的端口 每个Tomcat项目可以使用不同的端口号(如9090、9091、9092等),并通过Docker容器分别…...
【react】使用antd Table渲染数据遇到的报错问题
记录自己在开发过程中遇到的报错问题: 目录 原本写法:错误分析:解决方案: 原本写法: render: (text) > {console.log(text, "111111text");console.log(typeof text, "111111text");return t…...
JVM之垃圾回收器G1概述的详细解析
G1(并发) G1 特点 G1(Garbage-First)是一款面向服务端应用的垃圾收集器,应用于新生代和老年代、采用标记-整理算法、软实时、低延迟、可设定目标(最大 STW 停顿时间)的垃圾回收器,用于代替 CMS࿰…...
1.15寒假作业
web:nss靶场ez_ez_php 打开环境,理解代码 使用个体传参的方法,首先代码会检查file参数的前三个字符是不是php,如果是就输出nice,然后用include函数包含file,绕过不是则输出hacker,如果没有file…...
RK356x bsp 5 - 海华AW-CM358SM Wi-Fi/Bt模组调试记录
文章目录 1、环境介绍2、目标3、海华AW-CM358SM3.1、基本信息3.2、支持SDIO3.03.3、电气特性 4、适配流程步骤5、SDIO控制器适配5.1、sdio dts配置5.2、验证 6、Wi-Fi 适配6.1、wifi dts配置6.2、驱动移植6.2.1、kernel menuconfig6.2.2、传统驱动移植6.2.3、RK SDK WIFI/BT驱动…...
支持Google Analytics快捷添加的CMS:费用与部署形式详解
CMS 的费用和部署形式是选择平台的重要参考因素,不同的业务需求需要不同的解决方案。本文将从费用和部署形式两个角度,详细分析支持 Google Analytics 快捷集成的 CMS 和工具,帮助您更好地了解这些平台的特点。 1. BigCommerce 费用ÿ…...
CSS | 实现三列布局(两边边定宽 中间自适应,自适应成比)
目录 示例1 (中间自适应 示例2(中间自适应 示例3(中间自适应 示例4 (自适应成比 示例5(左中定宽,右边自适应 示例6(中间自适应 示例7(中间自适应 示例8(中间定宽…...
fpga系列 HDL:跨时钟域同步 双触发器同步器
目录 **双触发器同步器(Two-Flip-Flop Synchronizer)示例代码**:双触发器同步器的优缺点优点:缺点:适用场景: 应用实例:同步来自spi_slave的单个使能信号 跨时钟域的设计需要特别小心࿰…...
金融项目实战 05|Python实现接口自动化——登录接口
目录 一、代码实现自动化理论及流程 二、脚本实现的理论和准备工作 1、抽取功能转为自动化用例 2、搭建环境(测试工具) 3、搭建目录结构 三、登录接口脚本实现 1、代码编写 1️⃣api目录 2️⃣script目录 2、断言 3、参数化 1️⃣编写数据存储文件:jso…...
《HTML在网络安全中的多面应用:从防范攻击到安全审查》
Html基础 Html简介 HTML(HyperText Markup Language,超文本标记语言)是用于描述网页内容和结构的标准语言。以下是对HTML的简要介绍: 基本概念 定义: HTML不是一种编程语言,而是一种标记语言。 它使用标…...
Linux网络 | 学习传输层网络协议之UDP(短篇)
前言: 本节内容正式迈入传输层网络协议的知识殿堂, 之前的文章, 我们都是在应用层进行翻来覆去。 比如http就是应用层协议, 只不过使用了tcp的系统调用。 从本节开始, 友友们将会学习传输层两大协议: UDP和…...
iOS - 内存屏障的使用场景
内存屏障的使用是为了解决以下几个关键问题: 1. CPU 乱序执行 // 没有内存屏障时,CPU 可能乱序执行 void example() {// 这两行代码可能被 CPU 重排序a 1; // 操作1flag true; // 操作2 }// 使用内存屏障确保顺序 void safeExample() {a 1;…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
高等数学(下)题型笔记(八)空间解析几何与向量代数
目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...
破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...
门静脉高压——表现
一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构:由肠系膜上静脉和脾静脉汇合构成,是肝脏血液供应的主要来源。淤血后果:门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血,引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...
PLC入门【4】基本指令2(SET RST)
04 基本指令2 PLC编程第四课基本指令(2) 1、运用上接课所学的基本指令完成个简单的实例编程。 2、学习SET--置位指令 3、RST--复位指令 打开软件(FX-TRN-BEG-C),从 文件 - 主画面,“B: 让我们学习基本的”- “B-3.控制优先程序”。 点击“梯形图编辑”…...
GC1808:高性能音频ADC的卓越之选
在音频处理领域,高质量的音频模数转换器(ADC)是实现精准音频数字化的关键。GC1808,一款96kHz、24bit立体声音频ADC,以其卓越的性能和高性价比脱颖而出,成为众多音频设备制造商的理想选择。 GC1808集成了64倍…...
【Ragflow】26.RagflowPlus(v0.4.0):完善解析逻辑/文档撰写模式全新升级
概述 在历经半个月的间歇性开发后,RagflowPlus再次迎来一轮升级,正式发布v0.4.0。 开源地址:https://github.com/zstar1003/ragflow-plus 更新方法 下载仓库最新代码: git clone https://github.com/zstar1003/ragflow-plus.…...
