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

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

我的个人主页
我的专栏:Java-数据结构,希望能帮助到大家!!!点赞❤ 收藏❤

在这里插入图片描述


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

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

题目视图:

题目详解代码:

// 定义链表节点类classListNode{int val;ListNode next;ListNode(int x){ val = x; next =null;}}publicclassPartitionList{publicListNodepartition(ListNode pHead,int x){// 创建两个虚拟头节点,分别用于存储小于 x 和大于等于 x 的节点ListNode smallDummy =newListNode(0);ListNode largeDummy =newListNode(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;}publicstaticvoidmain(String[] args){// 创建测试链表 1 -> 4 -> 3 -> 2 -> 5 -> 2ListNode head =newListNode(1); head.next =newListNode(4); head.next.next =newListNode(3); head.next.next.next =newListNode(2); head.next.next.next.next =newListNode(5); head.next.next.next.next.next =newListNode(2);PartitionList solution =newPartitionList();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.链表的回⽂结构。题目链接

题目视图:

题目详解代码:

packageDemo1_28;/** * Created with IntelliJ IDEA. * Description: * User:Lenovo * Date:2025-01-28 * Time:20:04 */// 定义链表节点类classListNode{int val;ListNode next;ListNode(int x){ val = x; next =null;}}publicclassPalindromeLinkedList{publicbooleanisPalindrome(ListNodeA){if(A==null||A.next ==null){returntrue;}// 步骤 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;}// 反转链表的方法privateListNodereverseList(ListNode head){ListNode prev =null;ListNode curr = head;while(curr !=null){ListNode nextTemp = curr.next; curr.next = prev; prev = curr; curr = nextTemp;}return prev;}publicstaticvoidmain(String[] args){// 创建测试链表 1 -> 2 -> 2 -> 1ListNode head =newListNode(1); head.next =newListNode(2); head.next.next =newListNode(2); head.next.next.next =newListNode(1);PalindromeLinkedList solution =newPalindromeLinkedList();// 调用 isPalindrome 方法判断链表是否为回文结构boolean isPalindrome = solution.isPalindrome(head);System.out.println(isPalindrome);}}
在这里插入图片描述

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

题目视图:

题目详解代码:

packageDemo1_28;/** * Created with IntelliJ IDEA. * Description: * User:Lenovo * Date:2025-01-28 * Time:20:08 */// 定义链表节点类classListNode{int val;ListNode next;// 构造函数,用于初始化节点的值ListNode(int x){ val = x; next =null;}}publicclassIntersectionOfTwoLinkedLists{// 查找两个链表相交的起始节点的方法publicListNodegetIntersectionNode(ListNode headA,ListNode headB){// 如果其中一个链表为空,直接返回 nullif(headA ==null|| headB ==null){returnnull;}// 初始化两个指针分别指向两个链表的头节点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;}publicstaticvoidmain(String[] args){// 创建示例链表// 链表 A: 1 -> 2 -> 3 -> 6 -> 7ListNode headA =newListNode(1); headA.next =newListNode(2); headA.next.next =newListNode(3);// 链表 B: 4 -> 5 -> 6 -> 7ListNode headB =newListNode(4); headB.next =newListNode(5);// 创建相交部分ListNode intersection =newListNode(6); intersection.next =newListNode(7);// 连接链表 A 和相交部分 headA.next.next.next = intersection;// 连接链表 B 和相交部分 headB.next.next = intersection;// 创建 IntersectionOfTwoLinkedLists 类的实例IntersectionOfTwoLinkedLists solution =newIntersectionOfTwoLinkedLists();// 调用 getIntersectionNode 方法查找相交节点ListNode result = solution.getIntersectionNode(headA, headB);if(result !=null){System.out.println("相交节点的值为: "+ result.val);}else{System.out.println("两个链表不相交");}}}
在这里插入图片描述

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

题目视图:

题目详解代码:

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

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

题目链接

题目视图:

题目详解代码:

packageDemo1_28;/** * Created with IntelliJ IDEA. * Description: * User:Lenovo * Date:2025-01-28 * Time:20:15 */// 定义链表节点类classListNode{int val;ListNode next;ListNode(int x){ val = x; next =null;}}publicclassLinkedListCycleII{publicListNodedetectCycle(ListNode head){// 如果链表为空或只有一个节点,肯定没有环if(head ==null|| head.next ==null){returnnull;}// 慢指针,初始指向头节点,每次移动一步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){returnnull;}// 慢指针重新指向头节点 slow = head;// 快慢指针都以每次一步的速度移动,再次相遇的节点就是环的入口节点while(slow != fast){ slow = slow.next; fast = fast.next;}return slow;}publicstaticvoidmain(String[] args){// 创建有环链表 1 -> 2 -> 3 -> 4 -> 2(环从节点 2 开始)ListNode node1 =newListNode(1);ListNode node2 =newListNode(2);ListNode node3 =newListNode(3);ListNode node4 =newListNode(4);// 构建链表连接关系 node1.next = node2; node2.next = node3; node3.next = node4;// 形成环 node4.next = node2;// 创建 LinkedListCycleII 类的实例LinkedListCycleII solution =newLinkedListCycleII();// 调用 detectCycle 方法找到环的入口节点ListNode result = solution.detectCycle(node1);if(result !=null){System.out.println("环的入口节点的值为: "+ result.val);}else{System.out.println("链表中没有环");}// 创建无环链表 1 -> 2 -> 3 -> 4ListNode nodeA =newListNode(1);ListNode nodeB =newListNode(2);ListNode nodeC =newListNode(3);ListNode nodeD =newListNode(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("链表中没有环");}}}
在这里插入图片描述


所有的链表题目就分享到着了继续加油❤👍!!!

Read more

【OpenClaw企业级智能体实战】第01篇:从零搭建你的第一个AI员工(原理+算法+完整代码+避坑指南)

【OpenClaw企业级智能体实战】第01篇:从零搭建你的第一个AI员工(原理+算法+完整代码+避坑指南)

摘要:随着AI从“对话时代”迈入“执行时代”,OpenClaw作为开源智能体框架,正在重塑人机协作模式——它不再是被动响应的工具,而是能主动执行任务的“AI员工”。本文基于真实技术原理与实操场景,从背景概念切入,拆解OpenClaw“感知-决策-执行”的核心逻辑,详解算法组件构建思路,并提供从零到一的完整实操流程(含可直接运行的Python代码)。内容兼顾新手入门与进阶提升,强调安全隔离部署原则,避开技术术语堆砌,聚焦实用价值。读者可通过本文掌握OpenClaw基础部署、自定义技能开发、记忆模块集成等核心能力,快速落地自动化办公、信息整理等实际场景,真正体验“低成本、高效率”的AI生产力革命。全文严格遵循真实性原则,无捏造案例与夸大描述,所有代码均经过实测验证。 优质专栏欢迎订阅! 【OpenClaw从入门到精通】【DeepSeek深度应用】【Python高阶开发:AI自动化与数据工程实战】 【YOLOv11工业级实战】【机器视觉:C# + HALCON】【大模型微调实战:平民级微调技术全解】 【人工智能之深度学习】【AI 赋能:Python 人工智能应用实战】

Ubuntu_24.04 安装OpenClaw教程

认识OpenClaw 官网:https://openclaw.ai/ https://docs.openclaw.ai/start/getting-started 安装OpenClaw curl -fsSL https://openclaw.ai/install.sh | bash 安装完成 配置命令 在终端输入: openclaw onboard 选择Yes 选择QuickStart 因为前面配置过,所以提示是否用原来的配置信息,可以使用Reset进行重置 选择模型: 根据自己的需要进行选择, 这里要特别注意一个问题,openClaw对上下文有要求,默认最小是16000Token,要不然后面安装的时候会报下图的错误信息 选择Qwen一直在waiting 如果要使用其他的模型,选择Custom Provider 如果选择DeepSeek,baseURL输入:https://api.deepseek.com/v1 然后输入API-KEY:sk-******* model输入:

【AI Coding 系列】——什么是AI Coding,怎么合理使用AI Coding,大模型上下文限制解决方案,任务拆解策略

【AI Coding 系列】——什么是AI Coding,怎么合理使用AI Coding,大模型上下文限制解决方案,任务拆解策略

AI Coding 并非简单的"让 AI 写代码",而是一种使用大型语言模型(LLM)为核心驱动力的新型软件编程方式。要求开发者不仅要理解编程语言,更要掌握模型边界感知、上下文工程、认知负载管理等新兴技能。 随着 Claude、GPT-4、Kimi 等模型的能力跃升,我们正从"AI 辅助编码"(Copilot 模式)变成"AI 主导架构,开发人员主导决策"的代理编程(Agentic Coding)。这一转变要求建立全新的工作流、质量控制体系和知识管理方法。 第一部分:核心概念、认知框架——小白扫盲(可直接看第二部分) 1.1 模型边界感知 AI Coding 的首要原则是清醒认知模型的能力边界。就是我们蒸米饭加多少水类似,

Flutter 组件 globe_cli 的适配 鸿蒙Harmony 实战 - 驾驭全球化云原生部署、实现鸿蒙端 Serverless 一键发布与跨地域加速方案

Flutter 组件 globe_cli 的适配 鸿蒙Harmony 实战 - 驾驭全球化云原生部署、实现鸿蒙端 Serverless 一键发布与跨地域加速方案

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 globe_cli 的适配 鸿蒙Harmony 实战 - 驾驭全球化云原生部署、实现鸿蒙端 Serverless 一键发布与跨地域加速方案 前言 在鸿蒙(OpenHarmony)生态走向国际化的新征程中,开发者面临的一个现实难题是:如何将原本适配国内环境的后端服务,以极低的成本、极高的速度部署到全球范围内的边缘节点?如何在没有专业运维团队支持的情况下,实现鸿蒙应用后端服务的“全球一键分发”? Serverless(无服务器架构)作为当代的开发范式,正逐渐成为解决这一问题的黄金利器。 globe_cli 是连接 Flutter/Dart 代码与 Globe 全球化 Serverless 平台的官方纽带。它能让你的 Dart 后端代码(如 API 服务、Mock 服务等)