链表找环的起点

原创 2017年11月03日 15:14:38

牛客网
思路:
1. 先使用快慢指针确定是否有环。原理
2. (1)方法1 如果有环,计算出环的长度,采用快慢指针,定位环起点
3. (2)方法2 如果有环,设置两个指针从链表头和快慢指针相遇点逐步前进,相遇点则是链表环起点。原理
方法一:

ListNode *detectCycle(ListNode *head) {
        ListNode *fast,*slow;
        fast = slow = head;
        while(fast&&fast->next&&fast->next->next){
              slow = slow->next;
              fast = fast->next->next;
              if(slow == fast) break;
        }
        if(!fast||!fast->next||!fast->next->next) return NULL;
        //寻找环的长度
        ListNode *p;
        int count;
        p = slow;
        count = 1;
        while(p->next!=slow){
            p = p->next;
            count ++;
        }
        p = head;
        for(int i = 0;i<count;i++)
            p = p->next;
        ListNode *c = head;
        while(p!=c){
            c = c->next;
            p = p->next;
        }
        return c;
    }

方法二:

    ListNode *detectCycle(ListNode *head) {
        ListNode *fast,*slow;
        fast = slow = head;
        while(fast&&fast->next&&fast->next->next){
              slow = slow->next;
              fast = fast->next->next;
              if(slow == fast) break;
        }
        if(!fast||!fast->next||!fast->next->next) return NULL;
        //寻找环的长度
        fast = head;
        while(fast!=slow){
            fast = fast->next;
            slow = slow->next;
        }
        return slow;
    }

分析:

  1. 为什么通过判断快慢指针是否相等可以判断环是否存在
    假设链表路径为:x + y,其中x为环之前的路径长度,y为环之后的路径长度
    慢指针追上快指针,则必然是在环中,无环只会差距越来越大。
    当快指针追上慢指针时有
    设fast: m,slow: n; (m,n分别为fast,slow指针移动的距离)

    {(mx)%y=(nx)%ym=2n

    =>[(n-x) + n]%y = (n-x) %y
    =>n是y的整数倍
    那么n是一步一步走的,则n必然可以为n的整数倍。
    则通过判断快慢指针是否相等可判断是否有环

  2. 找到相遇点如何求环的起点
    链表图
    设相遇为p,则划分环为cd 两段,c为已经走过的点,则
    x+c+k*(d+c) = 2*(x+c)
    => x = kd+(k-1)c
    => x = (k-1)(d+c) + c
    则设置两个指针一个指向链表头,一个指向相遇点,两个每次前进一步,相遇点则是环的起点

参考:链表环起点

版权声明:本文为博主原创文章,未经博主允许不得转载。

有环链表中寻找到环的起点

用2个辅助指针,第一个指针p1每次走一步,第二个指针p2每次走两步。当p1走到环的起点时走了a步,那么p2肯定在环中,而且走了2a步,距离环的起点是2a-a步。如果p1再走b步与p2相遇,那么就会有这...
  • zju_bigjar
  • zju_bigjar
  • 2015年10月01日 23:00
  • 460

证明利用快慢指针寻找有环单链表中环的起点算法

问题:给定一个有环单链表,找到链表中环的起点,也就是说,找到下图中的单链表中Join点: (本图来源于http://www.cnblogs.com/xudong-bupt/p/3667729.h...
  • l294265421
  • l294265421
  • 2016年01月07日 20:39
  • 1615

判断链表是否有环并求出环的起点

判断链表有无环的方法: 设置一个快指针速度  != 慢指针的速度,这就是物理里的相遇问题,我开始犯了一个错,我设置快指针和慢指针的速度相等,所以答案出错,原因是速度相等,那么它们在坐标轴上的速度永远...
  • Joyem123
  • Joyem123
  • 2016年06月14日 10:28
  • 428

【C语言】找带环单链表的环入口

思想:(1)快慢指针,先让快指针追上慢指针             (2)令快指针指向表头,慢指针的指向不变,两个指针同时开始走             (3)两个指针相遇时,所指节点即为环的入口 ...
  • ZDF0414
  • ZDF0414
  • 2015年11月26日 21:34
  • 339

如何判断单链表有环,并找出环的入口

如何判断单链表有环,并找出环的入口? 时间O(n)O(n),空间O(1)O(1)。 这个面试题还是蛮有趣的,当时只想出了第一问,第二问实在巧妙。 如图这个单链表,蓝色的部分是环。 对于如何...
  • u013250442
  • u013250442
  • 2016年04月17日 14:24
  • 2057

【面试题】-判断单链表是否有环并找到环入口(快慢指针)

快慢指针 所谓的快慢指针的快慢是指指针向前移动的步长。比如在单链表中,快指针每次向前移动2个步长,慢指针则每次向前移动1个步长。 单链表环 单链表有环的定义是链表的尾节点指向了链表中间的某个...
  • zwhlxl
  • zwhlxl
  • 2015年05月14日 21:57
  • 2056

数据结构与算法分析笔记与总结(java实现)--链表7:含环链表找环入口结点问题

数据结构与算法分析笔记与总结(java实现)--链表7:含环链表找环入口结点问题...
  • qq_27703417
  • qq_27703417
  • 2017年01月17日 21:10
  • 263

寻找单向循环链表的环的开始结点

寻找循环链表的循环初始结点
  • MMChinaMM
  • MMChinaMM
  • 2015年09月24日 20:26
  • 802

首先如何判断一个链表是否有环,并找出环的入口

http://blog.csdn.net/gukesdo/article/details/7516021 首先如何判断一个链表是否有环: 设置两个指针(fast, slow),初始值都...
  • imxiaosong
  • imxiaosong
  • 2015年04月08日 15:49
  • 4750

找出有环链表中环的起点

给定一个有环的链表,写一个算法,找出环的起点。 例如: 输入:A->B->C->D->E->C[与前面的C是同一个节点] 输出:C 判断一个链表是否存在环有一个简单的方法,就是使用一个快...
  • suwei19870312
  • suwei19870312
  • 2014年03月19日 22:27
  • 1066
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:链表找环的起点
举报原因:
原因补充:

(最多只允许输入30个字)