判断单链表中是否有环,找到环的入口节点

声明

  1. 文章可以随意转载,但请注明出处。
  2. 文中有一些地方引用了其他文章,但都已标明出处。如有侵犯,可立即删除。
  3. 文中有些地方并无冒犯之意,希望提及的博客作者理解。没有你们的帮助,对这个问题毫无头绪。
  4. 由于CSDN博客系统的内部错误,所有的公式后面都有一条恼人的竖线,实属无奈。
  5. 欢迎评论。

文章梗概

本文通过对现有资料的收集和整理,给出了一种相对简单的严格证明的“判断单链表是否有环,找到环的入口节点”的方法。

题目描述

一个链表中包含环,请找出该链表的环的入口结点(牛客网题目链接),题目中没有说是单链表,从给出的代码中可以看出是单链表而且不可修改链表元素的定义。

思考过程

从两个大的角度思考这个问题

1.记录遇到的每一个链表元素

在一次遍历过程中的,使用一种数据结构(数组、Hash表、基数树)记录遇到的每一个链表元素并判断是否已经遇到过,其中使用基数树可以获得)

的时间复杂度,但是可会有比较高的空间复杂度。

2.利用链表的性质

  • 在题目的讨论页看到了比较有想法的一个答案至_的答案,正如其所言时间复杂度为O(n),两个指针,一个在前面,另一个紧邻着这个指针,在后面。两个指针同时向前移动,每移动一次,前面的指针的next指向NULL。也就是说:访问过的节点都断开,最后到达的那个节点一定是尾节点的下一个,也就是循环的第一个。这时候已经是第二次访问循环的第一节点了,第一次访问的时候我们已经让它指向了NULL,所以到这结束。这样做的话过题目是可以了,但是会破坏掉原来的链表,所以并不是一个特别完美的解决办法。如果可以在链表元素中加入一个记录“逻辑断开”的元素,也就是说在遍历的过程中,不真正的断开元素之间的连接,而是使用一个记录值,记录下“逻辑上的断开”
  • 另一个答案页上比较正统的回答为0909的回答,其主要思想和蒙恩的罪人的新浪博客大同小异,优雅简洁,后面主要针对蒙恩的罪人的新浪博客进行讨论。

相关问题的解法与证明

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


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

使用追赶的方法,设定两个指针t

,均从头指针开始,每次分别前进1步、2步。如存在环,则两者相遇;如不存在环,L

退出。其中主要的思想就是“环形相遇追及问题”,理解上应该不复杂。

2.如何知道环的长度?

记录下问题1的相遇点,t

从该点开始,再次相遇时1

。选择问题1的相遇点为起始点是为了确保起始点为环上的一点。

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

设问题1中的相遇点为1

,赋值q

再次相遇所在的位置就是环的入口节点(环的连接点)。这里和上面提到的博客中的叙述差别非常大,这也是其有些问题的地方,我在这里更正了其说法,并给出了相对严格的证明。

相对简洁的实现

public class Solution {
   ListNode EntryNodeOfLoop(ListNode h){
        if(h == null || h.next == null)
            return null;
        ListNode slow = h;
        ListNode fast = h;
        while(fast != null && fast.next != null ){
            slow = slow.next;
            fast = fast.next.next;
            if(slow == fast){
                ListNode p=h;
                ListNode q=slow;//相当于让q指向了m1
                while(p != q){
                    p = p.next;
                    q = q.next;
                }
                if(p == q)
                    return q;
                }
        }
        return null;
}

 

代码及问题三的证明

我们把该链表抽象为这样一个模型,假设环长为n

情景1
判断单链表中是否有环找到环的入口节点
此图表示其实状态,其中h

表示链表头节点,t

表示环的入口节点。

情景2
判断单链表中是否有环找到环的入口节点
此图表示w

运动到了a
并且,经过观察可知b

,所以可知公式①:

 
b

 

情景3.
判断单链表中是否有环找到环的入口节点
此时,t

相遇在节点n为环的长度)。
同理在情况2中,从b

情景4.
判断单链表中是否有环找到环的入口节点
情况4对应着代码中的11

~}
值得高兴的是,在情况2中我们有公式①,观察到q
再次相遇在这里的作用是提供一个计数。
所以,当t

,也就是需要找的环的入口点。

复杂度

我们关注第一次循环的w

)

相关文章:

  • 2021-04-20
  • 2021-05-23
  • 2021-07-13
  • 2022-12-23
  • 2021-12-23
  • 2021-10-23
  • 2021-12-01
  • 2022-12-23
猜你喜欢
  • 2022-01-05
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-15
  • 2022-12-23
相关资源
相似解决方案