【数据结构与算法】(LeetCode)141.环形链表 142.环形链表Ⅱ

【数据结构与算法】(LeetCode)141.环形链表 142.环形链表Ⅱ

文章目录

引言

环形链表问题是数据结构与算法中的经典问题,在面试中出现频率极高。这类问题不仅考察对链表结构的理解,更考验解决问题的思维能力和数学分析能力。本文将详细分析环形链表的判断方法以及环入口节点的定位算法,帮助读者深入理解这一重要问题。

环形链表判断

问题描述

给定一个链表的头节点 head,判断链表中是否存在环。

在这里插入图片描述

解决方案:快慢指针法

快慢指针法是解决环形链表问题的经典方法,其核心思想是使用两个指针以不同速度遍历链表。

bool hasCycle(structListNode*head){structListNode* slow=head,*fast=head;while(fast&&fast->next){ slow=slow->next; fast=fast->next->next;//一定要先让快慢指针走,再判断 因为一开始快慢指针都是headif(slow==fast)return true;}return false;}

原理分析

为什么快慢指针一定能相遇?

假设慢指针进入环时,快指针与慢指针之间的距离为N。由于快指针每次比慢指针多走一步,它们之间的距离会逐次减少:N, N-1, N-2, …, 2, 1, 0。因此最终一定会相遇。

步长选择的数学分析

为什么选择一步和两步?

当快指针每次走三步、四步或更多时,情况会变得更加复杂。以三步为例:

  • 每次移动后,快慢指针之间的距离减少2
  • 当N为偶数时,可以追上
  • 当N为奇数时,会错过,距离变为C-1(C为环长)
在这里插入图片描述

假设slow进环时,fast跟slow的距离是N

fast追击slow时 距离变化为N N-1 N-2 ……2 1 0

所以能追上

在这里插入图片描述

当fast等于3时,每次fast与slow距离就减2

1.当N为偶数时,可以追上

2.当N为奇数时,会错过,这时他们的距离会变为C-1 (假设C为环的长度)

a.如果C-1为偶数(C为奇数),下一轮就追上了

b.如果C-1为奇数(C为偶数),就永远追不上

所以这么一看,追不上的条件是:N为奇数并且C为偶数

在这里插入图片描述

但是这种情况存在吗?

进一步分析表明,当快指针走三步时,追不上的条件是:N为奇数且C为偶数。但通过数学推导可以证明这种情况实际上不可能发生:

假设slow走的距离是L

fast走的距离就是L+x*C+N (x为fast走的圈数)

fast走的距离是slow的3倍

3L=L+x*C+N

化简可得

2L=x*C+N

当C为偶数N为奇数时,x*C为偶数

等号左边是偶数,右边是偶数加奇数(也就是奇数),显然不成立

所以不存在N为奇数,C为偶数的情况

所以fast一定能追上slow

环形链表Ⅱ

题目如下

在这里插入图片描述

方法一

找到fast与slow相遇的位置meet,head与meet同时走,他们相遇位置就是环的入口

证明如下:

在这里插入图片描述

相遇时:

slow走的路程为:L+N

fast走的路程为: L+x*C+N

fast走的是slow的2倍

2(L+N)=L+x*C+N

化简可得

L=(x-1)*C+C-N

所以L的长度就是相遇点转了x-1圈 再走了C-N距离的点

这意味着:从头节点到环入口的距离L,等于从相遇点走(x-1)圈再加(C-N)步。因此,两个指针分别从头节点和相遇点出发,一定会在环入口相遇。

代码如下

structListNode*detectCycle(structListNode*head){structListNode* slow=head,*fast=head;while(fast&&fast->next){ slow=slow->next; fast=fast->next->next;if(slow==fast){structListNode* meet=slow;while(meet!=head){ head=head->next; meet=meet->next;}return meet;}}returnNULL;}

方法二:转换为相交链表问题

算法思路
  1. 找到快慢指针的相遇点
  2. 将环从相遇点处断开
  3. 问题转换为求两个链表的交点问题
在这里插入图片描述

将环形链表断开

newhead=meet->next

meet->next=NULL

这样就转换成了链表相交的问题

structListNode*getIntersectionNode(structListNode*headA,structListNode*headB){structListNode* curA=headA,*curB=headB;int lenA=1,lenB=1;while(curA->next){ curA=curA->next; lenA++;}while(curB->next){ curB=curB->next; lenB++;}int gap=abs(lenA-lenB);//假设法 先假设A长structListNode* longList=headA;structListNode* shortList=headB;if(lenA<lenB){ longList=headB; shortList=headA;}while(gap--){ longList=longList->next;}while(longList){if(longList==shortList)return longList; longList=longList->next; shortList=shortList->next;}returnNULL;}structListNode*detectCycle(structListNode*head){structListNode* slow=head,*fast=head;while(fast&&fast->next){ slow=slow->next; fast=fast->next->next;if(slow==fast){structListNode* meet=slow;structListNode* newhead=meet->next; meet->next=NULL;returngetIntersectionNode(head,newhead);}}returnNULL;}

实际应用与扩展

应用场景

  1. 内存管理:检测内存泄漏或循环引用
  2. 状态机检测:验证有限状态机是否会进入循环状态
  3. 递归检测:判断递归函数是否会无限递归
    meet->next=NULL;
    return getIntersectionNode(head,newhead);
    }}

return NULL;

}

 ## 实际应用与扩展 ### 应用场景 1. **内存管理**:检测内存泄漏或循环引用 2. **状态机检测**:验证有限状态机是否会进入循环状态 3. **递归检测**:判断递归函数是否会无限递归 4. **哈希冲突解决**:在开放定址法中检测哈希表是否已满 

Read more

开源神器Spec-Kit和OpenSpec:AI开发工作流的双剑合璧指南

开源神器Spec-Kit和OpenSpec:AI开发工作流的双剑合璧指南

文章概要 作为一名在AI开发工具链里摸爬滚打多年的老司机,我曾被Spec-Kit的800行文档吓退,也被OpenSpec的极简主义惊艳。直到发现它们根本不是竞争对手,而是互补神器!本文将用实战经验告诉你:Spec-Kit如何像严谨的架构师构建知识体系,OpenSpec怎样如敏捷的极客快速落地,以及最关键的——如何让它们像咖啡与牛奶般完美融合。 还记得第一次看到Spec-Kit生成的800行文档时,我差点把咖啡喷在显示器上——这哪是开发工具,分明是AI界的百科全书!而当我遇见OpenSpec,它用250行代码就完成了同样任务,那一刻我仿佛看到了极简主义大师在向我微笑。但真正的惊喜是:它们根本不是对手,而是AI开发界的咖啡与牛奶! Spec-Kit就像那个永远穿着西装三件套的严谨架构师,它带着你从宪法制定开始,一步步分解任务,生成详尽到令人发指的用户故事和测试计划。800行的文档不是负担,而是一座精心构建的知识宝库。每个需求都要经过八步验证,就像瑞士军刀的每个小工具都各司其职——从/specify到/archive,它确保你永远不会在深夜三点因为"忘记考虑边界条件"而崩溃。 “工具没

By Ne0inhk
【源力觉醒 创作者计划】文心开源大模型ERNIE-4.5私有化部署保姆级教程与多功能界面窗口部署

【源力觉醒 创作者计划】文心开源大模型ERNIE-4.5私有化部署保姆级教程与多功能界面窗口部署

* 按照我这个路线来部署,网速快五分钟就能零基础跑通模型 一起来轻松玩转文心大模型吧👉一文心大模型免费下载地址: https://ai.gitcode.com/theme/1939325484087291906 计算机配置 组件配置GPUNVIDIA A8000 SXM4 80GB × 1CPU15 核处理器内存249GB 内存硬盘系统盘 100GB + 数据盘 50GB * 部署使用的电脑都是只有系统的云电脑,部署过程中的性能差异,评估它们的运行效率和资源消耗,从而为不同需求的开发者和研究者提供参考依据。 * 文心模型汇总 环境配置与部署 1. 更换镜像源(使用阿里云镜像源): sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak sudo sed -i 's|http://archive.ubuntu.com/

By Ne0inhk
开源新势力:openGauss 在数字时代企业级开源库选型核心的竞争力

开源新势力:openGauss 在数字时代企业级开源库选型核心的竞争力

前言 在 AI 与大数据深度融合的数字化浪潮中,数据形态正从单一结构化向 “结构化 + 非结构化” 混合形态演进。而数据库作为企业数据资产的核心载体,其选型直接关系到业务连续性、数据安全性与技术前瞻性。随着开源技术成为企业级应用的主流选择,市场对数据库的需求已从单纯的 “存储与查询”,升级为对 “高性能、高安全、高可用、智能化” 综合能力的诉求。 openGauss 作为源于华为技术沉淀的企业级开源关系型数据库,凭借架构创新、技术突破与生态共建,已成为越来越多关键行业的选型之一。下面,我们就来探究 openGauss 在数据库选型中究竟具备哪些竞争力! 一、openGauss 向量数据库简介 openGauss是一款全面友好开放,携手伙伴共同打造的企业级开源关系型数据库。openGauss提供面向多核架构的极致性能、全链路的业务、数据安全、基于AI的调优和高效运维的能力。其核心架构采用 “内核 + 引擎” 的模块化设计,内核层面保留关系型数据库的 ACID 事务特性,引擎层面则集成 DataVec 向量数据库能力,形成 “结构化

By Ne0inhk

完全免费!用阿里开源 CoPaw 养一只属于自己的 AI 小助理(魔搭启动,亲测有效)

先说一个小插曲:前几天我写了一篇介绍 Maxclaw 的文章,当时还是免费的,结果文章发出去没多久,Minimax 就悄悄改了规则,变成 39 元一个月起步了。当然,39 元其实也不贵——毕竟你去闲鱼搜"openclaw 代安装",随便一个人工服务都要 50 块往上走。但既然有完全免费的方案,为什么不用呢? 今天这篇,就给大家介绍一个我亲自跑通的、完全免费的方案:用阿里开源的 CoPaw,在魔搭创空间里一键启动,服务器免费,Token 每天 2000 次免费调用,不用装任何本地环境,浏览器打开就能用。 CoPaw 是什么?先用一分钟搞清楚 很多人第一次听到 CoPaw 这个名字,会以为是某种宠物应用。其实它的全称是 Co Personal Agent Workstation,是阿里

By Ne0inhk