潇洒撸代码

不断学习,不断思考,努力做更好

链表找环的起点

牛客网
思路:
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
    则设置两个指针一个指向链表头,一个指向相遇点,两个每次前进一步,相遇点则是环的起点

参考:链表环起点

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hujinglovekmg/article/details/78435952
文章标签: 链表
个人分类: c++算法
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

链表找环的起点

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭