一、如何判断一个单链表是否有环
1) 基本思路,将链表中的每一个节点都利用哈希表存储,然后遍历链表查看是否有节点位置在哈希表中发生冲突。
2) 课程解法
设置两个指针一个“快指针”一个“慢指针”
快指针: 一次走两步
慢指针: 一次走一步
然后利用“快指针”、“慢指针”同时变量链表,如果“快指针”和“慢指针”相遇,表示链表有环。
如果“快指针”遇到null,表示链表无环。
二、找到环的交点(链表中环的入口节点)
解法接着上面的解法2, 在“快指针”与“慢指针”相遇之后,再在链表入口添加一个新的“慢指针”和原先的“慢指针”同步,它们相遇的节点就是环的入口节点。
课程中只给出了结论没有给出证明过程,这里给出证明的过程。
慢指针的速度为 v
快指针的速度为 2v
它们在 t 时刻相遇
环外的链表长度为 m
环内的链表长度为 n
链表的拓扑结构有两种情况:
有如下关系:
2vt - m = xn + vt - m ---> vt = xn (其中x为整数且大于等于1)
如果为拓扑一结构,那么”慢指针“当前就在环的入口节点,放置”新慢指针“的位置就是在环入口。
如果为拓扑二结构, 那么”慢指针“在环内距离入口节点 (xn - m) % n 的位置,”新慢指针“走过m距离后到达环入口节点,这个时候,”慢指针“也刚好到达环入口节点, 两指针相遇。
三、有两个链表,判断他们是否有交点
按照两个链表是否有环可以分为一下三种情况, 第二组图是它们相交后的拓扑结构。
在单链表中,一个有环一个无环的情况,是不可能相交的。
解题步骤:
判断两个链表是否有环
如果都无环,可以利用哈希表来解决,找到第一个冲突的节点
如果一个有环,一个无环,直接 判断没有交点
如果都有环,判断环的入口节点是否相等,利用步骤2的方法;如果不相等,遍历一次环中的节点,看是否能找到第二个链表的入口节点,如果能找到,这表示相交,随便返回一个环的入口节点。如果找不到,则链表不相交。
代码以后补上