数据结构_找环,破环题-2.5

一. 判断单链表有无环

a. 错误的思路:遍历陷入死循环

1)和相交的遍历思路一样,找指向相同。

错误点

一直在死循环。

思考点:如何破环

b. 个人思路:反转链表回首结点

1)目前的经验,无非就是增删查改,反转链表,快慢指针,于是一个个靠;
2)发现,反转有环链表后,会回到首结点
图解思路如图1:
ssss

图1 反转有环链表大体流程

增益点:反转破环

反转链表可以跳出环的死循环。

代码

typedef struct ListNode Node;
bool hasCycle(struct ListNode* head) {if (head == NULL)return false;Node* n1 = NULL;Node* n2 = head;Node* n3 = NULL;while (n2){n3 = n2->next;n2->next = n1;n1 = n2;n2 = n3;if (n3)n3 = n3->next;}if (n1 == head && head->next != NULL) 回到首结点就是有环return true;return false;
}

c. 参考思路:快慢指针转为追及问题

1)环相当于初中还是高中的一道物理题:在学校操场上,小狗速度是小猫的两倍,问小狗多久能追上小猫。即快指针为慢指针速度的两倍;
2)速度为两倍的考究点为,2-1=1,保证每次只追一个结点距离,实现追及结点遍历,避免陷入奇偶死循环的局面。

增益点:思路本身和二倍速度遍历所有结点

代码

typedef struct ListNode Node;
bool hasCycle(struct ListNode *head) {if(head==NULL||head->next==0)return false;Node* fast=head;Node* slow=head;Node* n3=NULL;while(fast){fast=fast->next;if(fast)fast=fast->next;slow=slow->next;if(slow==fast)return true;}return false;
}

二. 有环,返回入环结点地址

a. 个人思路一:继续反转链表找思路(缺陷就是无用遍历多了些)

1)发现在反转思路出环的状态会出现一个反向新环
2)遍历反向新环得到入环结点地址。
图解思路如图2:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/0fece3bbcb534614928f194064a0a681.png#pic_center在这里插入图片描述

图2 反转过程形成的反向新环

图中,对应反转后的一次移位,利用这个反向新环的任意一结点store去遍历这个环,如果与n1地址相同,则n1为入环地址。

未解决的问题:编译器对的,oj不对

编译器结果如图3:

在这里插入图片描述

图3 编译器的监视窗口数据

从图中可以看出,store是找到了n1,并返回了n1的地址。

oj结果如图4:

在这里插入图片描述

图4 oj输出

输出是这没环?我编译器一步一步调试都是对的,还找到了入环结点,怎么到你这就找不到了?而且最开始思考的图解思路也是没错的。

代码

typedef struct ListNode Node;
struct ListNode* detectCycle(struct ListNode* head) {if (head == NULL)return NULL;Node* n1 = NULL;Node* n2 = head;Node* n3 = NULL;Node* store = NULL;while (n2){n3 = n2->next;n2->next = n1;n1 = n2;n2 = n3;if (n3)n3 = n3->next;store = n1;while (store)     没环一定到NULL,有环就一直循环直到找到n1{store = store->next;if (store == n1)return n1;}}return NULL;}

b . 个人思路二:快慢指针公式求解,没做出来

列出未知数,如图5:
在这里插入图片描述

图5 快慢指针追及图

其中x为入环前跳数,y为慢指针入环后跳数,z为剩余跳数。

1)慢指针跑不了一个环,则x+y可知;
2)相遇后,再次跑一圈可以得到环的结点数:z+y+1。
3)快指针跳数:x+y+nz(n未知);
4)慢指针跳数:x+y;
5)二倍速,中点数量关系:2*(x+y)=x+y+n*(y+z+1)。
四个未知数,三个等式,求不出来。

c . 参考思路一:未知数n无所谓

看成:
C=y+z+1;环结点数
2*(x+y)=x+y+nC;
x=C-y+(n-1)C;
可以看作,C-y是跑了(n-1)C的圈后的最后一圈位置。
(n-1)C相当于是白跑了(n-1)圈,不必知道n的具体大小。即从快慢指针相遇点出发一定能和head出发相遇

增益点:无,过于具体题目具体分析了

代码

typedef struct ListNode Node;
struct ListNode * detectCycle(struct ListNode *head) {if (head == NULL)return NULL;Node* slow = head;Node* fast = head;Node* store = NULL;while(fast){fast=fast->next;if(fast)fast=fast->next;slow=slow->next;if(slow==fast)break;}if(fast!=slow)return NULL;store= slow;while(head!=store){head=head->next;if(store)store=store->next;}return store;}

d . 参考思路二:我把环手动断开不就行了?还死循环?

1)快慢指针判断有无环;
2)有环,相遇点直接截断;
3)转换为两个链表求相交问题。移步至相交问题。

增益点:数学家思维

高中数学老师讲过数学家思维:
数学家知道烧水过程是把水倒进壶里,点火,烧水。
在面对一壶装满冷水的水时,
数学家会:把水倒掉--------》把水倒进壶里,点火,烧水
正常人会:点火,烧水

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

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

相关文章

STM32F1 - 点灯-寄存器模式

点灯 实验概述:Step1> 建立工程Step2> 宏定义 - 寄存器地址 实验概述: 用配置寄存器的方式,开关一个LED灯, 只用标准库中提供的启动文件, Step1> 建立工程 出现错误:导入文件类型错误 keil5编译中…

ELAdmin后台启动

版本选择 ELAdmin官网地址:https://eladmin.vip/ 有 JPA 和 MyBatis两个版本,之前只有 JPA,考虑到国内复杂的业务情况增加了 MyBatis 版本。我最终也选择了使用 MyBatis版本。 代码 仓库地址:https://gitee.com/elunez/eladmin…

【日志记录】——单片机可执行文件合并

一:需求场景 现在有一片单片机,执行程序包括自定义boot和应用程序app, 在将打包好的固件给到生产时有以下问题,由于要通过jlink烧录boot,然后上电启动boot,通过boot烧录初始化程序,过程过于复杂&#xff0…

物联网自动虫情测报仪器

TH-CQ3S在农业生产的进程中,病虫害的防治始终是关键的一环。然而,传统的病虫害监测手段往往存在着效率低下、准确度不高等问题,这无疑给农业生产带来了巨大的困扰。好在,随着科技的飞速发展,一款基于物联网技术的自动虫…

【问题篇】activiti工作流转办并处理备注问题

当处理activiti转办问题时,需要做的就是处理审批人和备注问题。 处理的思路是,先将当前环节标志成转办标签,再通过BUSINESS_KEY_找到流程实例的历史记录,找到最新的一条复制一份出来,表示需要转办到的人的历史记录并设…

RecombiMAb anti-mouse Ly6G,1A8-CP129单克隆抗体

1A8-CP129单克隆抗体是原始1A8单克隆抗体的重组嵌合型抗体。可变结构域序列与原始1A8相同,但是恒定区序列已经从大鼠IgG2a变为小鼠IgG2a。1A8-CP129单克隆抗体像原始克隆号的大鼠IgG2a抗体一样,不包含Fc突变。 1A8-CP129单克隆抗体与小鼠Ly6G反应。Ly6G分…

C# CAD交互界面-自定义工具栏(二)

运行环境 vs2022 c# cad2016 调试成功 一、引用 acdbmgd.dllacmgd.dllaccoremgd.dllAutodesk.AutoCAD.Interop.Common.dllAutodesk.AutoCAD.Interop.dll using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.T…

2. Maven 继承与聚合

目录 2. 2.1 继承 2.2继承关系 2.2.1 思路分析 2.2.2 实现 2.1.2 版本锁定 2.1.2.1 场景 2.1.2.2 介绍 2.1.2.3 实现 2.1.2.4 属性配置 2.2 聚合 2.2.1 介绍 2.2.2 实现 2.3 继承与聚合对比 maven1:分模块设计开发 2. 在项目分模块开发之后啊&#x…

基于Vue的移动端UI框架整理

一、Vant 官方地址:https://youzan.github.io/vant/#/zh-CN/ 简介:有赞公司开发。 特性:60 高质量组件、90% 单元测试覆盖率、完善的中英文文档和示例、支持按需引入、支持主题定制、支持国际化、支持 TS、支持 SSR。 特别说明&#xff1…

Java老兵 转C语言,需要学习的点(最易懂的解释)

一、static 1.1 修饰函数内的局部变量: void sayHi(void) { static int index 5;index; }多次调用sayHi函数,index 5 只有在第一次调用的时候初始化一次,后面的多次调用,此句话就不执行了。 1.2 修饰全局变量或…

python将Word页面纸张方向设置为横向

通过python-docx的章节属性,就可以更改纸张方向、纸张尺寸。 import docx from docx.enum.section import WD_ORIENT from docx.shared import Cmdocument docx.Document() section document.sections[0]# 设置纸张大小为A4大小 section.page_width Cm(21) sect…

JAVA建造者模式详解

建造者模式 1 建造者模式介绍 建造者模式 (builder pattern), 也被称为生成器模式 , 是一种创建型设计模式. 定义: 将一个复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。 **建造者模式要解决的问题 ** 建造者模式可以将部件和其组装过程分开…