判断单链表是否带环且返回节点

         今天鄙人为大家带来的是一道简单的逻辑运算题。用用到了一个我们在链表中提及过的方法快慢法。这道题其实没啥考的实际意义。只是我们如果能了解这道题的解决方法的话。对我们后面梳理逻辑会有很大的帮助。

单链表的题目

     我们可以看到上面的题目。就是让我们判断是否带环。也许大家这样看起来可能不是很直观,那么我们重新画一个图,大家看着可能会更好一点。

        大家可以看到这个图里面给我表示的是这个链表没有进环的地步。然后有一个竖直的黑点,就是他们环相交的地方。那么我们只需要判断是否存在这么一个点,那么就是不是能够判断是否带环了。 那么我们如何来判断他们是否有这么个点呢?然后这就是我们开始在序言中说的快慢指针的方法了。那什么叫快慢指针呢?快慢指针就是一个快,一个慢慢。例如一个指针每次走一步,一个指针每次走两步。我们以这个图为例。当慢支撑走了我的一半的话,那么快指针就已经走到他们的相交点了(就是那个黑色柱子)。当慢指针走到那个焦交点的时候,快指针已经在c里面走了一段时间了。然后当慢指针继续往前走,快指针也快速走。那么这就变成了我们的追赶问题了。如果带环的话,那么快指针一定会追慢指针的,因为我比你快一步,那么相当于我每次去和你的距离都会减一。无论我们会计人是走两步还是走三步走四步都会追上。如果是走技术的话,那么就是相当于转第二圈才能追上。并且这个不存在追不上的问题。我们经过认证证明是一定会追上的,不存在不上的条件。如果你的距离是奇数的话,那么就要转两圈才能追上,如果是偶数,则第一圈就追上了。

       但是我们前面都是考虑的带环的,我们肯定也有不带环的呀。那么我们是不是当快指针或者快指针的下一步为NULL了?那么就代表他们走到结尾了,说明他们就不带环了。

       那有没有存在当慢指针走到了相交节点?快指针还没有追上他呢。大家需要注意一下,这是不存在的。因为当慢指针走到相交节点就代表了他已经转了c一圈了。因为我们快指针比慢指针快。动漫直升都走了一圈了,快指针还没追上,那么就代表这个是不存在的。

       我想当大家看到这里了,应该也大概了解了我们这个的解题思路是什么。就是创建两个指针从头开始往前走,一个走一步,一个走两步。当快指针与慢指针相等,那么就代表他们有还我们就返回ture否则就返回false

代码实现

        其实这个就是很经典的想出来很难写出来很简单的问题了。我们上面也说过,我就是创建两个新节点,从头开始走,如果相遇了,那就返回ture反之亦然。

bool hasCycle(struct ListNode *head) {
    struct ListNode* man=*head;
    struct ListNode* kuai=*head;
    while(kuai&&kuai->next)
    {
      man=man->next;
      kuai=kuai->next->next;
 
    if(man=kuai)
     return ture;
    }
    return false;
}

        这写出来是很简单的。主要是大家能知道这个方法就好很多了。大家知道这个思想,但是如果我们在力扣上回答这个问题的话,需要变一下。但是我们思想是正确的。毕竟我用他们自己的这个题目的解题都会有报错。不知道为什么。

返回节点

        

          我们要返回节点的话,就是相当于我们要返回那个黑色的柱子A。我们在前面也说过了,h和相遇就代表有环,所以我们需要判断是否有a的话。我们有两种方法。但都会用到我们前面写的判断是否有环。因为我们要借用他们快慢相遇的那个节点。我们的第一种方法就是在快慢指针相遇的地方再创建一个节点。并且在l的开头创建一个节点,他们同时向是下走。当他们相遇,那么就返回这个节点,就说明这是我们的黑色柱子a了。大家会想想啊,这是为什么呀?为什么他们这就相遇了就返回这个节点了?大家可以看我接下来写一个公式,思考一下是不是这样的?

        其中Y代表的是快指针是慢直针的几倍,然后右边代表的快指针走的步数。左指针是慢指针走的步数。 我们以快指针针是慢指针的二倍来计算。

      其中x为快指针在c里面走了多少圈。这样看起来是不是减少出来?L就等于快慢指的相遇后面的节点嘛。 大家应该就了解很多了,那我们接下来就实现代码如何?

代码实现1

struct ListNode* meet=kuai;
while(meet!=head)
{
  meet=meet->next;
  head=head->next;
}
return meet

      大家看看这个代码是很简单的吧。那只需要创建一个新节点,就是在快慢指针的节点,然后一直循环。那么他们就一定会相遇,然后就返回这个节点就可以了。关于这个代码实现,大家最主要是理解它上面的公式是如何的。

代码实现2

       我们在前面说过,这是我们返回去的第一种方法,我们还有个第二种方法。其实整体上是差不太多的。我们在他们快慢指针相遇点后创建一个新节点。然后再将快慢指针后的原节点给置为空。那么我们创建的新节点,它就是剩下链表的头节点了。加上我们原本的那个链表现在就是两个单链表了。然后就演变成了我们的另外一个问题,两个链表相交的问题。

      那么接下来我们就直接写出链表相交的问题。然后大家就可以知道了。

       我们看一下这个图。那两个单列表如果想要有交点的话,他们的尾巴是不是相同的呀?因为是单链表嘛。我们无法向前走,但我们只能从前往后走。那么我们就都往后走,一直走到尾,今天之后我们判断是否相同,如果相同,那么就代表他们肯定会有交点,如果不同,我们就返回null。 

       但大家需要注意的是我们判断的并不是他们两个的值是不相同,而是判断的地址是不相同。因为如果我们判断值的话,我们很有可能尾部的值是相同的,但地址不相同。那么这是不是就是一个问题了?所以我们判断他们尾节点是否相同的话,我们需要判断的是地址。

        我们判断了他们有交点后。我看图片也可以看出来,有的列表长,有的列表短,我们这个也是需要单独判断的呀。那么我们怎么处理这件事情呢?我们从这些链表的头一起往后走的话,很有可能会错过这个交点。但是如果我们长的和短的从相同的位置开始出发的话,那么是否就会相遇了?因为我们知道当我们链表的长度相同的话,并且他们有焦点,那么焦点的位置相同,甚至说明他们前面的不是交点的部分也是相同的。那么我们现在就是需要过滤掉长的多的那一部分。所以我们是不是比较长链表与短链表,然后提前走掉他们相差的那部分,然后再一起往后走,判断他们相交的节点了。

       并且我们也知道我们前面要计算尾节点,那我们可以在尾节点的同时计算出它们的个数,这样是不是只有就方便了许多。

void xxxx(struct list* a, struct list* b)
{
	struct list *cur1 = a;
	struct list *cur2 = b;//两个新节点
	int y = 0;
	int h = 0;//记录数字
	while (cur1->next)
	{
		cur1 = cur1->next;
		y++;
	}
	while (cur2->next)
	{
		cur2 = cur2->next;
		h++;
	}//走到尾节点,并且记录数
	if (cur1 != cur2)
		return NULL;//尾节点是否相同
	int gap = abs(y - h);
	struct list* max = cur1; struct list*min = cur2;
	if (y < h)
	{
		int max = cur2; int min = cur1;
	}//确立谁是快指针。假设法
	while (gap--)
	{
		max = max->next;
	}//快指针先走几步
	while (max!=min)
	{
		max = max->next;
		min = min->next;
	}//一起走,然后返回节点
	return max;
}

       上面的代码就是第二种方法的实现方法的,大家只需要在后面传入参数的时候将节点重新创建之后然后传头节点和这个节点就可以了。 

 总结

        大家最主要的是了解这个代码的逻辑。这些代码实际上是运行起来其实没有太大的作用,最主要的是大家的逻辑能力能够得到有所锻炼,这相当于我们平常学习的有教学意义。实践的话可能没有多大作用。然后这上面就是我想与大家分享的知识了,然后肯定还有一些方法,但我不是很清楚,希望大家能在评论区里面留言。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

深入了解 Android 中的 ViewStub

在 Android 开发中&#xff0c;性能优化一直是一个重要的话题。ViewStub 作为一种轻量级视图容器&#xff0c;可以帮助我们在合适的时机延迟加载视图&#xff0c;从而优化应用性能。本文将详细介绍 ViewStub 的概念、使用方法以及在实际开发中的应用场景。 什么是 ViewStub&am…

船舶行业信息安全解决方案介绍

船舶行业信息安全背景&#xff1a; 近年来随着经济复苏、疫情与国际形势影响国内外船舶海运业务蓬勃发展&#xff0c;在业务量激增的背景下出现多类信息安全事件。其中2017年&#xff0c;马士基集团遭到勒索软件攻击&#xff0c;内部业务系统和码头操作系统均受到严重影响&…

【计算机视觉(11)】

基于Python的OpenCV基础入门——图像梯度变换 图像梯度变换Sobel算子Scharr算子Laplacian算子 图像梯度变换的代码实现以及效果图 图像梯度变换 图像梯度变换可以用于边缘检测、特征提取、增强图像和压缩图像等多种任务。图图像梯度可以把图像看成二维离散函数&#xff0c;图像…

深入二进制安全:全面解析Protobuf

前言 近两年&#xff0c;Protobuf结构体与Pwn结合的题目越来越多。 23年和24年Ciscn都出现了Protobuf题目&#xff0c;24年甚至还出现了2道。 与常规的Pwn题利用相比&#xff0c;只是多套了一层Protobuf的Unpack操作。 本文包含Protobuf环境安装、相关语法、编译运行以及pb…

【吊打面试官系列-Mysql面试题】Myql 中的事务回滚机制概述 ?

大家好&#xff0c;我是锋哥。今天分享关于 【Myql 中的事务回滚机制概述 ?】面试题&#xff0c;希望对大家有帮助&#xff1b; Myql 中的事务回滚机制概述 ? 事务是用户定义的一个数据库操作序列&#xff0c;这些操作要么全做要么全不做&#xff0c;是一个不可分割的工作单位…

keil MDK自动生成带版本bin文件

作为嵌入式单片机开发&#xff0c;在Keil MDK&#xff08;Microcontroller Development Kit&#xff09;中开发完编译完后&#xff0c;经常需要手动进行版本号添加用于发版&#xff0c;非常麻烦&#xff0c;如果是对外发行的话&#xff0c;更容易搞错&#xff0c;特此码哥提供一…

汉化版PSAI全面测评,探索国产AI绘画软件的创新力量

引言 随着AI技术的飞速发展&#xff0c;图像处理和绘画领域迎来了新的变革。作为一名AIGC测评博主&#xff0c;今天我们测评的是一款国产AI绘画软件——StartAI&#xff0c;一句话总结&#xff1a;它不仅在技术上毫不逊色于国际大牌&#xff0c;更在用户体验和本地化服务上做到…

自研一套带双向认证的Android通用网络库

当前&#xff0c;许多网络库基于Retrofit或OkHttp开发&#xff0c;但实际项目中常需要定制化&#xff0c;并且需要添加类似双向认证等安全功能。这意味着每个项目都可能需要二次开发。那么&#xff0c;有没有一种通用的封装方式&#xff0c;可以满足大多数项目需求&#xff1f;…

ABAP-03基础数据类型

基本数据类型 数据类型默认大小&#xff08;byte&#xff09;有效大小初始值说明示例C11-65535SPACE文本字符&#xff08;串&#xff09;‘Name’N11-65535‘00…0’数字文本‘0123’T66‘000000’时间(HHMMSS)‘123010’D88‘00000000’日期(yyyymmdd)‘20090901’I4-231~232…

win 打包java项目为exe一键部署,包括mysql和redis

需求&#xff1a;打包springboot项目在win系统下执行&#xff0c;并且要一键部署和开机启动 把所需的程序放在同一个文件夹 1.jdk文件夹&#xff1a;自己去下载&#xff0c;jdk8的话拿jre目录好了 2.mysql文件夹&#xff1a;是8.0.36版&#xff0c;270M精简版了 3.redis文件夹…

第58章SOCKET:TCP/IP网络基础

58.1 互联网 互联网会将不同的计算机网络连接起来并允许位于网络中的主机相互之间进行通信。互联网的目标是隐藏不同物理网络的细节以便向互联网中的所有主机呈现一个统一的网络架构&#xff0c;TCP/IP已经成了使用最为广泛的协议套件了&#xff0c; 术语Internet被用来指将全球…

智能语音新革命:有道与Azure的API服务对决

在当今技术飞速发展的时代&#xff0c;API&#xff08;应用程序接口&#xff09;已经成为连接不同软件和服务的桥梁。无论是开发移动应用、构建网页服务&#xff0c;还是实现物联网设备的互联互通&#xff0c;API都在其中扮演着不可或缺的角色。随着市场上各种API接口的涌现&am…

【Linux】—MySQL安装

文章目录 前言一、下载官方MySQL包二、下载完成后&#xff0c;通过xftp6上传到Linux服务器上三、解压MySQL安装包四、在安装目录下执行rpm安装&#xff0c;请按顺序依次执行。五、配置MySQL六、启动MySQL数据库七、退出&#xff0c;重新登录数据库 前言 本文主要介绍在Linux环境…

Linux系统编程——网络编程

目录 一、对于Socket、TCP/UDP、端口号的认知&#xff1a; 1.1 什么是Socket&#xff1a; 1.2 TCP/UDP对比&#xff1a; 1.3 端口号的作用&#xff1a; 二、字节序 2.1 字节序相关概念&#xff1a; 2.2 为什么会有字节序&#xff1a; 2.3 主机字节序转换成网络字节序函数…

Kantana和The Sandbox联手打造元宇宙娱乐的未来

The Sandbox 是一个开创性的元宇宙、游戏和创作平台&#xff0c;泰国领先的娱乐公司 Kantana 很高兴地宣布双方将建立合作关系&#xff0c;共同打造元宇宙娱乐的未来。 此次合作结合了 Kantana 引以为傲的故事讲述专长和The Sandbox 的用户生成内容 (UGC) 工具&#xff0c;创建…

若依框架自定义开发使用学习笔记(1)

因为我是跳着学的&#xff0c;原理那些都没咋看。 代码自动生成&#xff0c;依赖sql表 在ruoyi数据库中&#xff0c;创建你想要的表&#xff0c;这里我创建了个购物车表&#xff0c;由于空间有限&#xff0c;只能拍到这么多。 然后就可以在前端自动生成代码 点击导入按钮 …

家庭财务新助手,记录收支明细,一键导出表格,让您的家庭财务一目了然!

在繁忙的现代生活中&#xff0c;家庭财务管理常常成为一项令人头疼的任务。如何记录每一笔收支&#xff0c;如何清晰地掌握家庭财务状况&#xff0c;如何合理规划未来开支&#xff0c;这些都是我们需要面对的问题。然而&#xff0c;有了这款家庭财务助手——晨曦记账本&#xf…

入侵检测系统(IDS)

入侵检测 入侵检测&#xff08;Intrusion Detection&#xff09;是指发现或确定入侵行为存在或出现的动作&#xff0c;也就是发现、跟踪并记录计算机系统或计算机网络中的非授权行为&#xff0c;或发现并调查系统中可能为视图入侵或病毒感染所带来的异常活动。 入侵检测系统 …

【案例分析】一文讲清楚SaaS产品运营的六大杠杆是什么?具体怎么运用?

在SaaS&#xff08;软件即服务&#xff09;行业&#xff0c;如何快速获取用户并实现持续增长一直是企业关注的重点。近年来&#xff0c;分销裂变策略因其高效性和低成本特性&#xff0c;成为许多SaaS企业实现快速增长的秘诀。下面&#xff0c;我们将通过一个具体的案例来剖析成…

大语言模型的昨天、今天和明天

引言 近年来&#xff0c;人工智能&#xff08;AI&#xff09;技术突飞猛进&#xff0c;其中大语言模型&#xff08;LLM&#xff09;无疑是最引人瞩目的技术之一。从OpenAI的GPT系列到Meta的Llama模型&#xff0c;大语言模型的发展不仅改变了人们对AI的认知&#xff0c;也在各行…