【Java-数据结构】Java 链表面试题下 “最后一公里”:解决复杂链表问题的致胜法宝

在这里插入图片描述

我的个人主页
我的专栏Java-数据结构,希望能帮助到大家!!!点赞❤ 收藏❤
在这里插入图片描述
在这里插入图片描述

引言:
Java链表,看似简单的链式结构,却蕴含着诸多有趣的特性与奥秘,等待我们去挖掘。它就像一个神秘的宝藏迷宫,每一个特性都是隐藏在迷宫深处的珍贵宝藏。链表的环,如同迷宫中的循环通道,一旦进入,便可能陷入无尽的循环;链表节点的唯一性与重复性,仿佛迷宫中的岔路,有的道路独一无二,有的却似曾相识;而链表的长度变化,又如同迷宫的动态扩展与收缩。在接下来的题目中,你将化身为勇敢的探险家,深入链表特性的迷宫,运用你的编程智慧,解开一个个谜题。通过检测链表的环、分析节点的重复性以及精准计算链表长度,你将逐渐揭开链表神秘的面纱,领略数据结构背后的奇妙逻辑。

6.编写代码,以给定值x为基准将链表分割成两部分,所有⼩于x的结点排在⼤于或等于x的结点之前—链表分割

题目视图:
在这里插入图片描述

题目详解代码:

// 定义链表节点类
class ListNode {int val;ListNode next;ListNode(int x) {val = x;next = null;}
}public class PartitionList {public ListNode partition(ListNode pHead, int x) {// 创建两个虚拟头节点,分别用于存储小于 x 和大于等于 x 的节点ListNode smallDummy = new ListNode(0);ListNode largeDummy = new ListNode(0);// 分别指向两个新链表的当前节点ListNode smallTail = smallDummy;ListNode largeTail = largeDummy;// 遍历原链表ListNode current = pHead;while (current != null) {if (current.val < x) {// 如果当前节点的值小于 x,将其连接到 small 链表的尾部smallTail.next = current;smallTail = smallTail.next;} else {// 如果当前节点的值大于等于 x,将其连接到 large 链表的尾部largeTail.next = current;largeTail = largeTail.next;}// 移动到下一个节点current = current.next;}// 断开 large 链表的尾部,防止出现循环largeTail.next = null;// 将 small 链表和 large 链表连接起来smallTail.next = largeDummy.next;// 返回重新排列后的链表的头节点return smallDummy.next;}public static void main(String[] args) {// 创建测试链表 1 -> 4 -> 3 -> 2 -> 5 -> 2ListNode head = new ListNode(1);head.next = new ListNode(4);head.next.next = new ListNode(3);head.next.next.next = new ListNode(2);head.next.next.next.next = new ListNode(5);head.next.next.next.next.next = new ListNode(2);PartitionList solution = new PartitionList();int x = 3;// 调用 partition 方法进行重新排列ListNode newHead = solution.partition(head, x);// 打印重新排列后的链表ListNode current = newHead;while (current != null) {System.out.print(current.val + " ");current = current.next;}}
}

在这里插入图片描述

7.链表的回⽂结构。题目链接

题目视图:在这里插入图片描述

题目详解代码:

package Demo1_28;/*** Created with IntelliJ IDEA.* Description:* User:Lenovo* Date:2025-01-28* Time:20:04*/
// 定义链表节点类
class ListNode {int val;ListNode next;ListNode(int x) {val = x;next = null;}
}public class PalindromeLinkedList {public boolean isPalindrome(ListNode A) {if (A == null || A.next == null) {return true;}// 步骤 1:找到链表的中间节点ListNode slow = A;ListNode fast = A;while (fast.next != null && fast.next.next != null) {slow = slow.next;fast = fast.next.next;}// 步骤 2:反转链表的后半部分ListNode secondHalf = reverseList(slow.next);// 步骤 3:比较链表的前半部分和反转后的后半部分ListNode p1 = A;ListNode p2 = secondHalf;boolean result = true;while (result && p2 != null) {if (p1.val != p2.val) {result = false;}p1 = p1.next;p2 = p2.next;}// 步骤 4:恢复链表的原始结构slow.next = reverseList(secondHalf);return result;}// 反转链表的方法private ListNode reverseList(ListNode head) {ListNode prev = null;ListNode curr = head;while (curr != null) {ListNode nextTemp = curr.next;curr.next = prev;prev = curr;curr = nextTemp;}return prev;}public static void main(String[] args) {// 创建测试链表 1 -> 2 -> 2 -> 1ListNode head = new ListNode(1);head.next = new ListNode(2);head.next.next = new ListNode(2);head.next.next.next = new ListNode(1);PalindromeLinkedList solution = new PalindromeLinkedList();// 调用 isPalindrome 方法判断链表是否为回文结构boolean isPalindrome = solution.isPalindrome(head);System.out.println(isPalindrome);}
}

在这里插入图片描述

8.输⼊两个链表,找出它们的第⼀个公共结点。—题目链接

题目视图:
在这里插入图片描述

题目详解代码:

package Demo1_28;/*** Created with IntelliJ IDEA.* Description:* User:Lenovo* Date:2025-01-28* Time:20:08*/
// 定义链表节点类
class ListNode {int val;ListNode next;// 构造函数,用于初始化节点的值ListNode(int x) {val = x;next = null;}
}public class IntersectionOfTwoLinkedLists {// 查找两个链表相交的起始节点的方法public ListNode getIntersectionNode(ListNode headA, ListNode headB) {// 如果其中一个链表为空,直接返回 nullif (headA == null || headB == null) {return null;}// 初始化两个指针分别指向两个链表的头节点ListNode pA = headA;ListNode pB = headB;// 当两个指针不相等时,继续循环while (pA != pB) {// 如果 pA 到达链表 A 的末尾,将其指向链表 B 的头节点pA = pA == null ? headB : pA.next;// 如果 pB 到达链表 B 的末尾,将其指向链表 A 的头节点pB = pB == null ? headA : pB.next;}// 返回相交节点,如果不相交则返回 nullreturn pA;}public static void main(String[] args) {// 创建示例链表// 链表 A: 1 -> 2 -> 3 -> 6 -> 7ListNode headA = new ListNode(1);headA.next = new ListNode(2);headA.next.next = new ListNode(3);// 链表 B: 4 -> 5 -> 6 -> 7ListNode headB = new ListNode(4);headB.next = new ListNode(5);// 创建相交部分ListNode intersection = new ListNode(6);intersection.next = new ListNode(7);// 连接链表 A 和相交部分headA.next.next.next = intersection;// 连接链表 B 和相交部分headB.next.next = intersection;// 创建 IntersectionOfTwoLinkedLists 类的实例IntersectionOfTwoLinkedLists solution = new IntersectionOfTwoLinkedLists();// 调用 getIntersectionNode 方法查找相交节点ListNode result = solution.getIntersectionNode(headA, headB);if (result != null) {System.out.println("相交节点的值为: " + result.val);} else {System.out.println("两个链表不相交");}}
}

在这里插入图片描述

9.给你一个链表的头节点 head ,判断链表中是否有环。—题目链接

题目视图:在这里插入图片描述

题目详解代码:

// 定义链表节点类
class ListNode {int val;ListNode next;// 构造函数,用于初始化节点的值ListNode(int x) {val = x;next = null;}
}public class LinkedListCycle {// 判断链表是否有环的方法public boolean hasCycle(ListNode head) {// 如果链表为空或者只有一个节点,肯定没有环if (head == null || head.next == null) {return false;}// 慢指针,初始指向头节点,每次移动一步ListNode slow = head;// 快指针,初始指向头节点的下一个节点,每次移动两步ListNode fast = head.next;// 当慢指针和快指针不相等时,继续循环while (slow != fast) {// 如果快指针到达链表末尾或者快指针的下一个节点是末尾,说明没有环if (fast == null || fast.next == null) {return false;}// 慢指针移动一步slow = slow.next;// 快指针移动两步fast = fast.next.next;}// 如果跳出循环,说明慢指针和快指针相遇了,链表有环return true;}public static void main(String[] args) {// 创建有环链表 1 -> 2 -> 3 -> 4 -> 2(环从节点 2 开始)ListNode node1 = new ListNode(1);ListNode node2 = new ListNode(2);ListNode node3 = new ListNode(3);ListNode node4 = new ListNode(4);// 构建链表连接关系node1.next = node2;node2.next = node3;node3.next = node4;// 形成环node4.next = node2;// 创建 LinkedListCycle 类的实例LinkedListCycle solution = new LinkedListCycle();// 调用 hasCycle 方法判断链表是否有环boolean result = solution.hasCycle(node1);System.out.println("链表是否有环: " + result);// 创建无环链表 1 -> 2 -> 3 -> 4ListNode nodeA = new ListNode(1);ListNode nodeB = new ListNode(2);ListNode nodeC = new ListNode(3);ListNode nodeD = new ListNode(4);// 构建无环链表连接关系nodeA.next = nodeB;nodeB.next = nodeC;nodeC.next = nodeD;// 再次调用 hasCycle 方法判断无环链表是否有环result = solution.hasCycle(nodeA);System.out.println("链表是否有环: " + result);}
}

在这里插入图片描述

10.给定⼀个链表,返回链表开始⼊环的第⼀个节点。 如果链表⽆环,则返回 NULL

—题目链接

题目视图:在这里插入图片描述

题目详解代码:

package Demo1_28;/*** Created with IntelliJ IDEA.* Description:* User:Lenovo* Date:2025-01-28* Time:20:15*/
// 定义链表节点类
class ListNode {int val;ListNode next;ListNode(int x) {val = x;next = null;}
}public class LinkedListCycleII {public ListNode detectCycle(ListNode head) {// 如果链表为空或只有一个节点,肯定没有环if (head == null || head.next == null) {return null;}// 慢指针,初始指向头节点,每次移动一步ListNode slow = head;// 快指针,初始指向头节点,每次移动两步ListNode fast = head;boolean hasCycle = false;// 寻找是否有环while (fast != null && fast.next != null) {slow = slow.next;fast = fast.next.next;// 快慢指针相遇,说明有环if (slow == fast) {hasCycle = true;break;}}// 如果没有环,返回 nullif (!hasCycle) {return null;}// 慢指针重新指向头节点slow = head;// 快慢指针都以每次一步的速度移动,再次相遇的节点就是环的入口节点while (slow != fast) {slow = slow.next;fast = fast.next;}return slow;}public static void main(String[] args) {// 创建有环链表 1 -> 2 -> 3 -> 4 -> 2(环从节点 2 开始)ListNode node1 = new ListNode(1);ListNode node2 = new ListNode(2);ListNode node3 = new ListNode(3);ListNode node4 = new ListNode(4);// 构建链表连接关系node1.next = node2;node2.next = node3;node3.next = node4;// 形成环node4.next = node2;// 创建 LinkedListCycleII 类的实例LinkedListCycleII solution = new LinkedListCycleII();// 调用 detectCycle 方法找到环的入口节点ListNode result = solution.detectCycle(node1);if (result != null) {System.out.println("环的入口节点的值为: " + result.val);} else {System.out.println("链表中没有环");}// 创建无环链表 1 -> 2 -> 3 -> 4ListNode nodeA = new ListNode(1);ListNode nodeB = new ListNode(2);ListNode nodeC = new ListNode(3);ListNode nodeD = new ListNode(4);// 构建无环链表连接关系nodeA.next = nodeB;nodeB.next = nodeC;nodeC.next = nodeD;// 再次调用 detectCycle 方法判断无环链表是否有环result = solution.detectCycle(nodeA);if (result != null) {System.out.println("环的入口节点的值为: " + result.val);} else {System.out.println("链表中没有环");}}
}

在这里插入图片描述
所有的链表题目就分享到着了继续加油❤👍!!!

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

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

相关文章

智慧园区系统的类型及其在企业管理效率提升中的关键作用解析

内容概要 在智慧园区的建设中&#xff0c;各类系统的采用是提升管理效率的关键所在。快鲸智慧园区(楼宇)管理系统&#xff0c;通过其全面数字化的管理手段&#xff0c;已经成为了企业管理的新标杆。这一系统能够有效整合租赁管理、资产管理、招商管理和物业管理等功能&#xf…

多级缓存(亿级并发解决方案)

多级缓存&#xff08;亿级流量&#xff08;并发&#xff09;的缓存方案&#xff09; 传统缓存的问题 传统缓存是请求到达tomcat后&#xff0c;先查询redis&#xff0c;如果未命中则查询数据库&#xff0c;问题如下&#xff1a; &#xff08;1&#xff09;请求要经过tomcat处…

第27篇 基于ARM A9处理器用C语言实现中断<三>

Q&#xff1a;基于ARM A9处理器怎样设计C语言工程&#xff0c;同时使用按键中断和定时器中断在红色LED上计数&#xff1f; A&#xff1a;基本原理&#xff1a;设置HPS Timer 0和按键中断源&#xff0c;主程序调用set_A9_IRQ_stack( )函数设置中断模式的ARM堆栈指针&#xff0c…

C++ 中用于控制输出格式的操纵符——setw 、setfill、setprecision、fixed

目录 四种操纵符简要介绍 setprecision基本用法 setfill的基本用法 fixed的基本用法 setw基本用法 以下是一些常见的用法和示例&#xff1a; 1. 设置字段宽度和填充字符 2. 设置字段宽度和对齐方式 3. 设置字段宽度和精度 4. 设置字段宽度和填充字符&#xff0c;结合…

【1.安装ubuntu22.04】

目录 参考文章链接电脑参数安装过程准备查看/更改引导方式查看/更改磁盘的分区格式关闭BitLocker加密压缩分区关闭独显直连制作Ubuntu安装盘下载镜像制作启动盘 进入BIOS模式进行设置Secure Boot引导项顺序try or install ubuntu 进入安装分区启动引导器个人信息和重启 参考文章…

代码随想录算法【Day34】

Day34 62.不同路径 思路 第一种&#xff1a;深搜 -> 超时 第二种&#xff1a;动态规划 第三种&#xff1a;数论 动态规划代码如下&#xff1a; class Solution { public:int uniquePaths(int m, int n) {vector<vector<int>> dp(m, vector<int>(n,…

计算机毕业设计PySpark+hive招聘推荐系统 职位用户画像推荐系统 招聘数据分析 招聘爬虫 数据仓库 Django Vue.js Hadoop

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

强化学习数学原理(三)——迭代算法

一、值迭代过程 上面是贝尔曼最优公式&#xff0c;之前我们说过&#xff0c;f(v)v&#xff0c;贝尔曼公式是满足contraction mapping theorem的&#xff0c;能够求解除它最优的策略和最优的state value&#xff0c;我们需要通过一个最优v*&#xff0c;这个v*来计算状态pi*&…

AI 浪潮席卷中国年,开启科技新春新纪元

在这博主提前祝大家蛇年快乐呀&#xff01;&#xff01;&#xff01; 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;其影响力已经渗透到社会生活的方方面面。在中国传统节日 —— 春节期间&#xff0c;AI 技术也展现出了巨大的潜力&#xff0c;为中国年带…

vim的特殊模式-可视化模式

可视化模式&#xff1a;按 v进入可视化模式 选中 y复制 d剪切/删除 可视化块模式: ctrlv 选中 y复制 d剪切/删除 示例&#xff1a; &#xff08;vim可视化模式的进阶使用&#xff1a;vim可视化模式的进阶操作-CSDN博客&#xff09;

sunrays-framework配置重构

文章目录 1.common-log4j2-starter1.目录结构2.Log4j2Properties.java 新增两个属性3.Log4j2AutoConfiguration.java 条件注入LogAspect4.ApplicationEnvironmentPreparedListener.java 从Log4j2Properties.java中定义的配置读取信息 2.common-minio-starter1.MinioProperties.…

相互作用感知的蛋白-小分子对接模型 - Interformer 评测

Interformer 是一个应用于分子对接和亲和力预测的深度学习模型&#xff0c;基于 Graph-Transdormer 架构的模型&#xff0c;利用相互作用&#xff08;氢键、疏水&#xff09;感知的混合密度网络&#xff08;interaction-aware mixture den sity network&#xff0c; MDN&#x…

Ceisum无人机巡检直播视频投射

接上次的视频投影&#xff0c;Leader告诉我这个视频投影要用在两个地方&#xff0c;一个是我原先写的轨迹回放那里&#xff0c;另一个在无人机起飞后的地图回显&#xff0c;要实时播放无人机拍摄的视频&#xff0c;还要能转镜头&#xff0c;让我把这个也接一下。 我的天&#x…

【漫话机器学习系列】065.梯度(Gradient)

梯度&#xff08;Gradient&#xff09; 在数学和机器学习中&#xff0c;梯度是一个向量&#xff0c;用来表示函数在某一点的变化方向和变化率。它是多变量函数的一阶偏导数的组合。 梯度的定义 设有一个标量函数 &#xff0c;它对 ​ 是可微的&#xff0c;则该函数在某一点的…

基于SpringBoot多数据源解决方案

最近在学习SpringBoot的时候&#xff0c;需要同时用两个不同的数据库连接服务&#xff0c;在网上学习了之后&#xff0c;下文以连接一个MySQL数据库和一个SqlServer数据库为例。 配置数据源连接信息 在配置文件中&#xff0c;配置对应的数据库连接信息&#xff0c;相比于单数…

二叉树的最大深度(C语言详解版)

一、摘要 嗨喽呀大家&#xff0c;leetcode每日一题又和大家见面啦&#xff0c;今天要讲的是104.二叉树的最大深度&#xff0c;思路互相学习&#xff0c;有什么不足的地方欢迎指正&#xff01;好啦让我们开始吧&#xff01;&#xff01;&#xff01; 二、题目简介 给定一个二…

穿心莲内酯(andrographolide)生物合成CYP72-文献精读106

Two CYP72 enzymes function as Ent-labdane hydroxylases in the biosynthesis of andrographolide in Andrographis paniculata 两种CYP72酶在穿心莲&#xff08;Andrographis paniculata&#xff09;中作为Ent-labdane羟化酶&#xff0c;在穿心莲内酯&#xff08;andrograp…

[SaaS] 内容创意生产平台

1.即梦 2.讯飞绘镜 typemovie 3.Krea.ai 4.Pika 5.runway 6.pixVerse 7.

DiffuEraser: 一种基于扩散模型的视频修复技术

视频修复算法结合了基于流的像素传播与基于Transformer的生成方法&#xff0c;利用光流信息和相邻帧的信息来恢复纹理和对象&#xff0c;同时通过视觉Transformer完成被遮挡区域的修复。然而&#xff0c;这些方法在处理大范围遮挡时常常会遇到模糊和时序不一致的问题&#xff0…

[c语言日寄]assert函数功能详解

【作者主页】siy2333 【专栏介绍】⌈c语言日寄⌋&#xff1a;这是一个专注于C语言刷题的专栏&#xff0c;精选题目&#xff0c;搭配详细题解、拓展算法。从基础语法到复杂算法&#xff0c;题目涉及的知识点全面覆盖&#xff0c;助力你系统提升。无论你是初学者&#xff0c;还是…