给定一个单链表,只给出头指针h:

1、如何判断是否存在环?

2、如何知道环的长度?

3、如何找出环的连接点在哪里?

4、带环链表的长度是多少?

解法:

1、对于问题1,使用追赶的方法,设定两个指针slow、fast,从头指针开始,每次分别前进1步、2步。如存在环,则两者相遇;如不存在环,fast遇到NULL退出。

2、对于问题2,记录下问题1的碰撞点p,slow、fast从该点开始,再次碰撞所走过的操作数就是环的长度s。

3、问题3:有定理:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分别从碰撞点、头指针开始走,相遇的那个点就是连接点。

该定理的证明可参考:http://fayaa.com/tiku/view/7/

4、问题3中已经求出连接点距离头指针的长度,加上问题2中求出的环的长度,二者之和就是带环单链表的长度

判断是否存在环的程序:

  1. bool IsExitsLoop(slist *head)
  2. {
  3. slist *slow = head, *fast = head;
  4. while ( fast && fast->next )
  5. {
  6. slow = slow->next;
  7. fast = fast->next->next;
  8. if ( slow == fast ) break;
  9. }
  10. return !(fast == NULL || fast->next == NULL);
  11. }

寻找环连接点(入口点)的程序:

  1. slist* FindLoopPort(slist *head)
  2. {
  3. slist *slow = head, *fast = head;
  4. while ( fast && fast->next )
  5. {
  6. slow = slow->next;
  7. fast = fast->next->next;
  8. if ( slow == fast ) break;
  9. }
  10. if (fast == NULL || fast->next == NULL)
  11. return NULL;
  12. slow = head;
  13. while (slow != fast)
  14. {
  15. slow = slow->next;
  16. fast = fast->next;
  17. }
  18. return slow;
  19. }

______________________________________________________________________________

______________________________________________________________________________

编程之美:判断两链表是否相交

《编程之美》里面有一篇是讲如何判断两链表是否相交,读后觉得原文太过啰嗦。于是,笔者总结了一下,此类问题可以扩展为两大类,分别是:

1、单链表与环问题http://blog.csdn.net/liuxialong/archive/2011/06/20/6555850.aspx

2、单链表相交与环问题(本文)


给定两单链表A、B,只给出两头指针。请问:

1、如何判断两单链表(无环)是否相交?

有两种可取的办法:

(1)人为构环,将链表A的尾节点指向链表B,再判断是否构环成功?从链表B的头指针往下遍历,如果能够回到B,则说明相交

(2)判断两链表最后一个节点是否相同,如果相交,则尾节点肯定是同一节点

2、如何判断两单链表(不知是否有环)相交?

先判断是否有环,判断是否有环可以使用追逐办法,设置两个指针,一个走一步,一个走两步,如果能相遇则说明存在环

(1)两个都没环:回到问题1

(2)一个有环,一个没环:不用判断了,肯定两链表不相交

(3)两个都有环:判断链表A的碰撞点是否出现在链表B的环中,如果在,则相交。(相交时,环必定是两链表共有的)

3、如何寻找两相交链表(不知是否有环)的第一个相交节点?

同样,使用追逐办法先判断是否存在环,分情况讨论

(1)无环:人为构环,将链表A的尾节点指向链表B,则构成一个带环的单链表。这个问题就转换成寻找带环单链表的环入口节点。

解法参考:http://blog.csdn.net/liuxialong/archive/2011/06/20/6555850.aspx

(2)有环:计算出两链表的长度lA、lB,(环的长度和环到入口点长度之和就是链表长度)

计算带环链表长度,可参考http://blog.csdn.net/liuxialong/archive/2011/06/20/6555850.aspx

如果lA>lB,则链表A指针先走lA-lB,然后链表B指针开始走,两者相遇的点就是相交点

如果lB>lA,则链表B指针先走lB-lA,然后链表A指针开始走,两者相遇的点就是相交点

http://blog.csdn.net/liuxialong/article/details/6555850

http://blog.csdn.net/liuxialong/article/details/6556096

如何判断单链表是否存在环 & 判断两链表是否相交的更多相关文章

  1. 数据结构与算法系列2 线性表 链表的分类+使用java实现链表+链表源码详解

    数据结构与算法系列2.2 线性表 什么是链表? 链表是一种物理存储单元上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表的链接次序实现的一系列节点组成,节点可以在运行时动态生成,每个节点包括两个 ...

  2. 转 java - 如何判断单链表有环

    转自 https://blog.csdn.net/u010983881/article/details/78896293 1.穷举遍历 首先从头节点开始,依次遍历单链表的每一个节点.每遍历到一个新节点 ...

  3. 判断单链表是否有环,并找出环的入口python

    1.如何判断一个链表是否有环? 2.如果链表为存在环,如果找到环的入口点? 1.限制与要求 不允许修改链表结构. 时间复杂度O(n),空间复杂度O(1). 2.思考 2.1判断是否有环 如果链表有环, ...

  4. 单链表的回文判断(O(n)时间复杂度和O(1)的空间复杂度)

    对于单链表来说,判断回文最简单的方法就是遍历链表,将链表中的元素复制到数组中,然后对数组进行判断是否是回文数组,但是这不符合O(1)的空间复杂度. 由于空间复杂度的要求,需要就地操作链表,不能开辟多余 ...

  5. 141 Linked List Cycle(判断链表是否有环Medium)

    题目意思:链表有环,返回true,否则返回false 思路:两个指针,一快一慢,能相遇则有环,为空了没环 ps:很多链表的题目:都可以采用这种思路 /** * Definition for singl ...

  6. LeetCode 141. Linked List Cycle 判断链表是否有环 C++/Java

    Given a linked list, determine if it has a cycle in it. To represent a cycle in the given linked lis ...

  7. leetCode-linkedListCycle判断链表是否有环

    题目 Given a linked list, determine if it has a cycle in it. Follow up: Can you solve it without using ...

  8. 笔试算法题(27):判断单向链表是否有环并找出环入口节点 & 判断两棵二元树是否相等

    出题:判断一个单向链表是否有环,如果有环则找到环入口节点: 分析: 第一个问题:使用快慢指针(fast指针一次走两步,slow指针一次走一步,并判断是否到达NULL,如果fast==slow成立,则说 ...

  9. LeetCode 141. Linked List Cycle(判断链表是否有环)

    题意:判断链表是否有环. 分析:快慢指针. /** * Definition for singly-linked list. * struct ListNode { * int val; * List ...

随机推荐

  1. DB2 锁问题的监控和解决

    常见的锁问题包括: 锁等待 锁超时 锁升级 死锁 而根据问题的特性通常分为两种: 实时事件:问题正在发生 历史事件:问题已经过去 如果实时事件,DBA 可以通过查看表信息.GET SNAPSHOT 或 ...

  2. chrome浏览器开发者工具(一)

    一.Elements 在Element中主要分两块大的部分:HTML结构面板和操作dom样式.结构.时间的显示面板 二.Network Network是一个监控当前网页所有的http请求的面版,它主体 ...

  3. javaagent笔记及一个基于javassit的应用监控程序demo

    javaagent基本用法 定义入口premain public static void premain(String agentArgs, Instrumentation inst) { Syste ...

  4. jquery metadata 详解

    1.0的版本是这样的$.meta 2.0的版本是这样的$.metadata 很多插件的编写都用到了这个插件,个人感觉这个东西应该是jquery官方的.推荐使用2.0的版本, 因为现在官方上就是2.0的 ...

  5. 8.14_end

    the first interview 事件委托(ul.li) jsonp原理实现 印象最深的项目 each的实现 ajax的实现 性能优化的方法 判断Function和Boolean 印象最深的项目 ...

  6. 2.1 js 基础--select深入

    select     获取select下的所有option     用op=select.options         option属性:op[1].value,op[1].text;     // ...

  7. Linux文件夹和文件创建删除命令

    Linux删除文件夹命令 linux删除目录很简单,很多人还是习惯用rmdir,不过一旦目录非空,就陷入深深的苦恼之中,现在使用rm -rf命令即可.直接rm就可以了,不过要加两个参数-rf 即:rm ...

  8. MVVM - 事件转命令2

    在使用MVVM模式时, 按照模式的规则是尽量不直接使用事件. 所以对于以前一直使用事件模式的同行来说确实有点头疼. 还好微软给我们提供了几种间接使用事件(命令)的方法, 下面我就来看看这几种方法: I ...

  9. java 2018面试题-多线程汇总(含解答)

    学习,内容越多.越杂的知识,越需要进行深刻的总结,这样才能记忆深刻,将知识变成自己的.这篇文章主要是对多线程的问题进行总结的,因此罗列了自己整理的多线程的问题,都是自己觉得比较经典和一些大企业面试会问 ...

  10. gradle -v不是外部命令, 内部命令,或批处理文件

    安装完gradle并且配置了环境变量之后,使用windos+R,cmd 进入Dos命令gradle -v检测版本号出现了: 1 --首先找到gradle文件所在目录 一般是在C:\Users\su\. ...