带环链表的入口

带环的单链表:

如上图,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;       //结论:(交点到入口点的距离+环长度的整数倍) = 头到入口点的距离

template<class T>
ListNode<T>* List<T>::IsRingList()
{
    if (_head == NULL)
        return false;
    Node* fast = _head,* slow = _head,* Input;
    while (fast && fast->_next)
    {
        if (fast == slow)     //链表带环 输出环的长度和入口点
        {
            int count = 1;
            do
            {
                slow = slow->_next;
                fast = fast->_next->_next;
                ++count;
            } while (fast == slow);
            cout << "环的节点的个数为:" << count << endl;

            while (Input == slow)
            {
                Input = Input->_next;
                slow = slow->_next;
            }
            return Input;
        }
    }
    return NULL;
}
时间: 2024-12-29 01:31:31

带环链表的入口的相关文章

[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

[PHP] 算法-请找出带环链表的环的入口结点的PHP实现

给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null 1.找链表倒数第k个结点,输入一个链表,输出该链表中倒数第k个结点.第一个指针走(k-1)步,到达第k个节点,两个指针同时往后移动,当第一个结点到达末尾的时候,第二个结点所在位置就是倒数第k个节点了 2.原理有点像上面的,定义两个指针,一个是快指针每次走两步,一个是慢指针每次走一步,当两个相遇的时候,假设环的长度为n个结点,慢指针走x步,快指针走2x步,2x=x+kn ;x=kn; k暂时假定为1圈 ,也就是慢指针slow

关于相交链表、带环链表、链表深拷贝的思路整理

返回相交链表的交点:1.先求出两个链表的各自长度2.让长的先走他们的(长度差)步3.然后两者同时走,第一次相遇就是交点(返回该结点) 判断链表是否带环:1.快慢指针(快的走两步,慢的走一步,不能一个一步,一个n步(N>2),可能会错过)2.如果两个指针相遇,则链表带环:如果快的遇到null,则不带环(直线形) 求入环点:1).转化为相交问题(求取相遇结点)2).一个从起点,一个从交点,都每次走一步,第一次相遇点为入环点 相交+带环(六种情况) 复杂链表的复制1)简单复制无法解决(因为是浅拷贝)2

带环链表 II

单链表,问有没有环,若有,找到环的入口. Lintcode上挑战,只许使用常数的空间. 设一个快指针fast,一个慢指针slow,fast每次走2步,slow每次走1步. 若无相遇找到了链尾,则无环,若相遇了,则有环. 设从链头到环入口点走了a步,从环入口到相遇点走了x步,环长r.相遇时,slow走了s步,fast走了2s步. 有: s=a+x,  2s=a+nr+x. 所以a+x=nr->a=nr-x. 注意理解a=nr-x.意思是从链头走到环入口的 步数=再走n圈,并退x步.那刚好也在环入口

判断链表是否带环,以及环的入口

给出一个链表,先判断链表是否带环,如果带环,求出环的入口. 判断是否带环:用快慢指针.快指针每走两步,慢指针走一步,如果两者在某个点处相 遇,则链表带环. 下边给出函数的实现代码: typedef struct LinkNode { DataType data; struct LinkNode *next; }LinkNode,*pLinkNode; typedef struct LinkList { LinkNode *pHead; }LinkList,*pLinkList; pLinkNod

判断两个链表是否相交(带环)

解决方案: 1.找出链表1的环入口节点a1,链表2的环入口节点a2; 2.如果a1=a2; 说明两个链表可能在入环之前或者入环第一个节点相交:将a1,a2作为两个链表的最后一个节点,转化为不带环的链表相交:其实在这种情况下已经说明两个链表已经相交了. 3.如果a1!=a2;以a1为基准节点进行while循环,如果在循环中找到跟a2相同的节点,说明两个链表相交:如果没找到,说明不相交. #如果1个链表不带环,1个链表带环:则两个链表必不相交:

带环单链表

判断单链表是否带环: 定义两个快慢指针,快指针每次走两步,慢指针每次走一步,然后判断是否两个指针相遇.若相遇,则带环. 设慢指针走过的路程为s,则快指针走过的路程即为2s. 设从环头结点到环的入口点的距离为a. 设从环的入口点到两指针相遇点的距离为x. 设环的长度为m.快指针走了n圈. 由数学关系式可得:s = a + x    2s = a + n*m + x; 则  n*m = a + x; a = n*m - x; 求环的入口点方法:定义连个指针,一个指针从环的头结点开始走,另一个指针则从

1.6带环单链表

检测单链表中是否有环 方法一:蛮力法 定义一个集合用来存放结点的引用,并将其初始化为空,从链表的头结点开始向后遍历,每遍历到一个结点就判断集合中是否有这个结点的引用,如果没有,说明这个结点是第一次访问,还没有形成环,那么将这个结点的引用添加到集合中去.如果在集合中找到了同样的结点,那么说明这个结点已经被访问过了,于是就形成了环.这种方法的时间复杂度为O(n),空间复杂度也为O(n). 方法二 : 快慢指针遍历法 定义两个指针fast(快)与slow(慢),二者的初始值都指向链表头,指针slow每

笔试,面试,C/C++,判断单链表是否带环?若带环,求环长度,求环入口点(两种方法)

SListNode* IsRing(SListNode *&pHead) //判断链表是否有环,求相聚点 {  //判空.有.没有  //思路:两个指针从头开始一快(2步)一慢(1步),若最后可以相聚,则链表有环  if (pHead)  {   SListNode *fast = pHead;   SListNode *slow = pHead;   while (fast&&fast->next)   {    fast = fast->next->next;