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

数据结构(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值取出,存进一个数组中,但题目要求空间复杂度为O(n) 。

       第三种思路,翻转一半的链表。过程分为三步,第一步,找到链表的中间部分;第二步,将链表的一半进行翻转。我们在上一期中,已经实现了翻转链表和寻找链表的中间节点。

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与链表(三)

专栏&#xff1a;数据结构(Java版) 个人主页&#xff1a;手握风云 目录 一、链表中的经典面试题 1.1. 链表分割 1.2. 链表的回文结构 1.3. 相交链表 1.4. 环形链表 一、链表中的经典面试题 1.1. 链表分割 题目中要求不能改变原来的数据顺序&#xff0c;也就是如上图所示。…...

数据结构学习记录-数据结构概念

1 数据结构&#xff1a; 数据结构是计算机存储&#xff0c;管理数据的方式。 数据必须依据某种逻辑联系组织在一起存储在计算机内 数据结构研究的就是这种数据的存储结构和数据的逻辑结构。 1.1 数据的逻辑结构&#xff1a; 逻辑结构指的是数据本身之间的关系 集合&#x…...

【Linux】11.Linux基础开发工具使用(4)

文章目录 3. Linux调试器-gdb使用3.1 背景3.2 下载安装3.3 使用gdb查询3.4 开始使用 3. Linux调试器-gdb使用 3.1 背景 程序的发布方式有两种&#xff0c;debug模式和release模式 Linux gcc/g出来的二进制程序&#xff0c;默认是release模式 要使用gdb调试&#xff0c;必须…...

数据结构与算法之栈: LeetCode 1047. 删除字符串中的所有相邻重复项 (Ts版)

删除字符串中的所有相邻重复项 https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-string/ 描述 给出由小写字母组成的字符串 s&#xff0c;重复项删除操作会选择两个相邻且相同的字母&#xff0c;并删除它们在 s 上反复执行重复项删除操作&#xff0c;直到无…...

C++ 在线编译软件介绍、杭电OJ、北大OJ、力扣OJ

在线编译软件的话&#xff0c;可见下&#xff1a; https://www.jyshare.com/compile/12/ 杭州电子科技大学开发的一个免费的写代码地址 &#xff0c;杭电OJ https://bestcoder.hdu.edu.cn/ 北大OJ http://poj.org/ 力扣OJ 力扣 (LeetCode) 全球极客挚爱的技术成长平台...

Java学习笔记(二十三)

1 CacheEvict CacheEvict是Spring框架中用于清空缓存的注解。以下是对CacheEvict注解的详细介绍&#xff1a; 1.1 作用 CacheEvict注解的主要作用是删除缓存中的数据。在方法执行后或执行前&#xff08;根据配置&#xff09;&#xff0c;它可以清空指定的缓存项或整个缓存区…...

《AI赋能鸿蒙Next,开启智能关卡设计新时代》

在游戏开发领域&#xff0c;关卡设计是至关重要的一环&#xff0c;它直接影响着玩家的游戏体验和沉浸感。而随着人工智能技术的飞速发展&#xff0c;结合鸿蒙Next系统的强大功能&#xff0c;为游戏的智能关卡设计带来了全新的思路和方法。 利用AI学习玩家行为模式 在鸿蒙Next…...

js:正则表达式

目录 正则表达式的语法 定义 检测 检索 元字符 边界符 量词 字符类 表单判断案例 修饰符 过滤敏感词 正则表达式是一种用于匹配和操作文本的强大工具&#xff0c;它是由一系列字符和特殊字符组成的模式&#xff0c;用于描述要匹配的文本字符组合模式 正则表达式是一…...

linux环境使用docker部署多个war项目

如果你的需求是在一个服务器上部署多个Tomcat项目&#xff0c;并且每个项目需要独立运行&#xff0c;可以通过以下方式实现&#xff1a; 1. 使用不同的端口 每个Tomcat项目可以使用不同的端口号&#xff08;如9090、9091、9092等&#xff09;&#xff0c;并通过Docker容器分别…...

【react】使用antd Table渲染数据遇到的报错问题

记录自己在开发过程中遇到的报错问题&#xff1a; 目录 原本写法&#xff1a;错误分析&#xff1a;解决方案&#xff1a; 原本写法&#xff1a; render: (text) > {console.log(text, "111111text");console.log(typeof text, "111111text");return t…...

JVM之垃圾回收器G1概述的详细解析

G1(并发) G1 特点 G1&#xff08;Garbage-First&#xff09;是一款面向服务端应用的垃圾收集器&#xff0c;应用于新生代和老年代、采用标记-整理算法、软实时、低延迟、可设定目标&#xff08;最大 STW 停顿时间&#xff09;的垃圾回收器&#xff0c;用于代替 CMS&#xff0…...

1.15寒假作业

web&#xff1a;nss靶场ez_ez_php 打开环境&#xff0c;理解代码 使用个体传参的方法&#xff0c;首先代码会检查file参数的前三个字符是不是php&#xff0c;如果是就输出nice&#xff0c;然后用include函数包含file&#xff0c;绕过不是则输出hacker&#xff0c;如果没有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 的费用和部署形式是选择平台的重要参考因素&#xff0c;不同的业务需求需要不同的解决方案。本文将从费用和部署形式两个角度&#xff0c;详细分析支持 Google Analytics 快捷集成的 CMS 和工具&#xff0c;帮助您更好地了解这些平台的特点。 1. BigCommerce 费用&#xff…...

CSS | 实现三列布局(两边边定宽 中间自适应,自适应成比)

目录 示例1 &#xff08;中间自适应 示例2&#xff08;中间自适应 示例3&#xff08;中间自适应 示例4 &#xff08;自适应成比 示例5&#xff08;左中定宽&#xff0c;右边自适应 示例6&#xff08;中间自适应 示例7&#xff08;中间自适应 示例8&#xff08;中间定宽…...

fpga系列 HDL:跨时钟域同步 双触发器同步器

目录 **双触发器同步器&#xff08;Two-Flip-Flop Synchronizer&#xff09;示例代码**&#xff1a;双触发器同步器的优缺点优点&#xff1a;缺点&#xff1a;适用场景&#xff1a; 应用实例&#xff1a;同步来自spi_slave的单个使能信号 跨时钟域的设计需要特别小心&#xff0…...

金融项目实战 05|Python实现接口自动化——登录接口

目录 一、代码实现自动化理论及流程 二、脚本实现的理论和准备工作 1、抽取功能转为自动化用例 2、搭建环境(测试工具) 3、搭建目录结构 三、登录接口脚本实现 1、代码编写 1️⃣api目录 2️⃣script目录 2、断言 3、参数化 1️⃣编写数据存储文件&#xff1a;jso…...

《HTML在网络安全中的多面应用:从防范攻击到安全审查》

Html基础 Html简介 HTML&#xff08;HyperText Markup Language&#xff0c;超文本标记语言&#xff09;是用于描述网页内容和结构的标准语言。以下是对HTML的简要介绍&#xff1a; 基本概念 定义&#xff1a; HTML不是一种编程语言&#xff0c;而是一种标记语言。 它使用标…...

Linux网络 | 学习传输层网络协议之UDP(短篇)

前言&#xff1a; 本节内容正式迈入传输层网络协议的知识殿堂&#xff0c; 之前的文章&#xff0c; 我们都是在应用层进行翻来覆去。 比如http就是应用层协议&#xff0c; 只不过使用了tcp的系统调用。 从本节开始&#xff0c; 友友们将会学习传输层两大协议&#xff1a; UDP和…...

iOS - 内存屏障的使用场景

内存屏障的使用是为了解决以下几个关键问题&#xff1a; 1. CPU 乱序执行 // 没有内存屏障时&#xff0c;CPU 可能乱序执行 void example() {// 这两行代码可能被 CPU 重排序a 1; // 操作1flag true; // 操作2 }// 使用内存屏障确保顺序 void safeExample() {a 1;…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

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

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

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

系统掌握PyTorch:图解张量、Autograd、DataLoader、nn.Module与实战模型

本文较长&#xff0c;建议点赞收藏&#xff0c;以免遗失。更多AI大模型应用开发学习视频及资料&#xff0c;尽在聚客AI学院。 本文通过代码驱动的方式&#xff0c;系统讲解PyTorch核心概念和实战技巧&#xff0c;涵盖张量操作、自动微分、数据加载、模型构建和训练全流程&#…...

comfyui 工作流中 图生视频 如何增加视频的长度到5秒

comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗&#xff1f; 在ComfyUI中实现图生视频并延长到5秒&#xff0c;需要结合多个扩展和技巧。以下是完整解决方案&#xff1a; 核心工作流配置&#xff08;24fps下5秒120帧&#xff09; #mermaid-svg-yP…...