有关有环链表的问题

首先有三点要说明:

1)在快指针追击慢指针时,如何保证快指针不会跨过慢指针而不会重合?

快指针总是能和慢指针重合,为什么?因为如果假如真的“跨过了”,那么慢指针在i位置,快指针在i+1位置。但是考虑上一步,慢指针必定在i-1位置,快指针也在i-1位置,所以在上一步时已经重合了!

2)为什么相遇时通过重置慢指针,然后让快慢指针以相同速度前进,再次相遇就是环的开始点?

这就要分析一下走的过程了。因为快指针走的速度是慢指针的两倍,那么如果慢指针走p步,则快指针走了2p步。现在假设环的开始节点距离head节点有k个距离,则当慢指针走了k步时,慢指针正好到环的开始节点D,与此同时,快指针也走了2k步,前k步走在环外,后k步走在环内。由于k可能比环的长度还大,所以我们让k = k % LOOP_SIZE。

现在有如下的结论:

- 慢指针在环的开始处

- 快指针在超前环k步的位置上

- 慢指针落后k步于快指针

快指针落后 LOOP_SIZE - k 步于慢指针!

- 快指针以慢指针2倍的速度追击慢指针。或者说快指针以1步的相对速度追击相对静止的慢指针。则需要LOOP_SIZE-k 才能追上慢指针。在I位置追上。

D -> I 的距离是 LOOP_SIZE - k, I -> D 的距离是k,这段距离恰好和A->D的距离相同,都是k !!!那么把慢指针放在head节点A,然后两个指针以相同速度前进,相遇处就是环的开始节点。

3)一个推论:快慢指针第一次相遇的地方和head的距离是环长度的整数倍。

假设相遇处离环开始点相距x个点,环长度为n个点
慢指针:k+qn+x=m (1)
又有2m-m=m=pn (2)
有(1),(2)可得:k+qn+x=pn
所以k+x = (p-q)n,即相遇处离head的距离为环长的整数倍.
所以将其中一个指针移至head,同时两指针以相同速度再次相遇即为环的开始处.

1.如何判断一个链表中有环

使用两个slow, fast指针从头开始扫描链表。指针slow 每次走1步,指针fast每次走2步。如果存在环,则指针slow、fast会相遇;如果不存在环,指针fast遇到NULL退出。

就是所谓的追击相遇问题:

2.求有环单链表的环长

在环上相遇后,记录第一次相遇点为Pos,之后指针slow继续每次走1步,fast每次走2步。在下次相遇的时候fast比slow正好又多走了一圈,也就是多走的距离等于环长。

  设从第一次相遇到第二次相遇,设slow走了len步,则fast走了2*len步,相遇时多走了一圈:

    环长=2*len-len。

3.求有环单链表的环连接点位置

  第一次碰撞点Pos到连接点Join的距离=头指针到连接点Join的距离,因此,分别从第一次碰撞点Pos、头指针head开始走,相遇的那个点就是连接点。

参考网址:http://www.cnblogs.com/xudong-bupt/p/3667729.html

       http://www.2cto.com/kf/201403/282309.html

有关有环链表的问题,布布扣,bubuko.com

时间: 2024-08-04 11:46:07

有关有环链表的问题的相关文章

数据结构Java实现04----循环链表、仿真链表

数据结构Java实现04----循环链表.仿真链表 单向循环链表 双向循环链表 仿真链表 一.单向循环链表: 1.概念: 单向循环链表是单链表的另一种形式,其结构特点是链表中最后一个结点的指针不再是结束标记,而是指向整个链表的第一个结点,从而使单链表形成一个环. 和单链表相比,循环单链表的长处是从链尾到链头比较方便.当要处理的数据元素序列具有环型结构特点时,适合于采用循环单链表. 和单链表相同,循环单链表也有带头结点结构和不带头结点结构两种,带头结点的循环单链表实现插入和删除操作时,算法实现较为

链表操作 -- 有环链表问题

参考: http://blog.163.com/[email protected]/blog/static/1113522592011828104617420/ 问题: 判断一个链表中是否有环. 分析: 我们都知道,当一个链表中没有环时,我们使用一个指针能从头遍历到尾:当链表中有环时,链表会在环中旋转. 当我们只使用一个链表指针时,可想到方法就是使用额外的数据结构来存储遍历过的每个节点,在遍历next节点时,判断next节点是否已存在于存储的节点中. 存储结构可以选择为hashTable,这样的

(原创)用Java实现链表结构对象:单向无环链表

转载请注明本文出处:http://www.cnblogs.com/Starshot/p/6918569.html 链表的结构是由一个一个节点组成的,所谓链,就是每个节点的头尾连在一起.而单向链表就是:每个节点包含了当前节点的值和下一个节点引用.双向链表就是每个节点包含了当前节点的值和上下两个节点的引用.相对于数组结构,链表的增删效率会更加高. 这边文章主要讲怎么用Java实现一个简单的链表结构:单向无环链表.以及实现一些数据处理的方法. 首先,新建一个节点类(本次例子中的节点值都是字符串类型):

C语言强化(七)链表相交问题_4 判断两个有环链表是否相交

上一节结束后,我们已经可以判断链表是否有环了,如果无环,那么按照前两节所讲的方法去判断链表是否相交以及获取相交结点,如果有环呢?怎么判断是否相交? 题目 给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交 解题步骤 判断两个[无环]链表是否相交 找到两个[无环]链表的相交结点 判断链表是否带环 判断两个[有环]链表是否相交 找到两个[有环]链表的相交结点 思路 对于有环的链表,只要它们相交,则带环的那一段必定完全重复.所以我们只需要在链表一上找到环上的一个结点,判断该结点是否在链

C语言强化(七)链表相交问题_5 找到两个有环链表的相交结点

有环链表是否相交我们也可以判断了,剩下的就是获得有环链表相交结点 题目 给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交 解题步骤 判断两个[无环]链表是否相交 找到两个[无环]链表的相交结点 判断链表是否带环 判断两个[有环]链表是否相交 找到两个[有环]链表的相交结点 思路: 显然,有环链表的相交点其实就是环的入口 如图 所以 问题转为求环的入口 直接上理论,具体解释不难,纯粹是一道小学数学追赶问题 若在头结点和快慢指针相遇结点分别设一指针,同步(单步)前进,则最后一定相遇

C语言强化(七)链表相交问题_1 判断无环链表相交

从此篇博文开始,讲解一道古老的链表相交问题,共五篇 题目 给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交 解题步骤 判断两个[无环]链表是否相交 找到两个[无环]链表的相交结点 判断链表是否带环 判断两个[有环]链表是否相交 找到两个[有环]链表的相交结点 此篇先从最简单的判断两个[无环]链表是否相交开始,顺便介绍一下链表的基础知识,方便一些对链表不太了解的同学学习. 基础知识 什么是链表? 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指

[LintCode] Linked List Cycle(带环链表)

描述 给定一个链表,判断它是否有环. 样例 给出 -21->10->4->5, tail connects to node index 1,返回 true. 这里解释下,题目的意思,在英文原题中,tail connects to node index 1 表示的是节点 5 还要链接回索引号 为 1 的节点. 一个典型的带环链表如下: 挑战 不要使用额外的空间 代码 GitHub 的源代码,请访问下面的链接: https://github.com/cwiki-us/java-tutoria

带环链表的入口

带环的单链表: 如上图,List 为一个带有环的单链表,环的大小为5: 证明: S 为 slow 指针相遇前走的距离,2S 为 fast 指针相遇前走过的距离: ∵ 2S = S + n*R;        //n slow,fast指针相遇前 fast 多经历的圈数  S = H_I + R1: ∴S = n*R; ∴n*R = H_I  + R1; ∵ R1 + R2 = R; ∴(n-1)*R = H_I - R2; ∴(n-1)*R + R2 = H_I;       //结论:(交点到

环链表的一些问题

1.判断单链表是否有环 使用两个slow, fast指针从头开始扫描链表.指针slow 每次走1步,指针fast每次走2步.如果存在环,则指针slow.fast会相遇:如果不存在环,指针fast遇到NULL退出. 就是所谓的追击相遇问题: 2.求有环单链表的环长 在环上相遇后,记录第一次相遇点为Pos,之后指针slow继续每次走1步,fast每次走2步.在下次相遇的时候fast比slow正好又多走了一圈,也就是多走的距离等于环长. 设从第一次相遇到第二次相遇,设slow走了len步,则fast走