判断单链表中是否有环?如果有起点在哪里?环长度?

需求:

        判断一个单链表是否有环?如果有换找出环的起点,以及环的长度。

分析:

        1)定义两个指针p1和p2,p1每次走1步,p2每次走两步,如果单链表有环则p1和p2一定会相遇;为什么一定有环一定会相遇?我们先定义一些变量:假设有环,环长为n,然后设 链表的起点环起点 的长度为a,p1到环的起点时p2位于环的位置为x(0<=x<n)。

        现在到这里就很容易的理解为什么一定会相遇,因为当p1到环的起点时,p2位于环的位置(距离环起点的顺时针位置)为x,那么p2与p1相差n-x步,而且p2每次总比p1块一步,所以一定会追上p1。

        2)设p2和p1第一次相遇的点位于环的位(置距离环起点的顺时针位置)为b,此时

            p1走的距离:a+b

           p2走的距离:p2速度是p1的二倍所以 2*(a+b),但是因为p1和p2相遇所以p2走的距离也是 a+b+n*k,即2*(a+b) == a+b+n*k,两边消去一个(a+b)

            所以推导出  a+b == n*k

        3)如何找环的起点,第一次相遇之后,把指针p1拉回到链表的起点,然后把p2的速度改为每次走一步即和p1速度相同,p2把第一次相遇点作为起点,那么当p1和p2再次相遇的点就是圈的起点,因为第二次相遇时p1刚好走a步到环的起点,p2刚好走b+a步,由于b+a == n*k刚好也在环的起点。

        

代码:

ListNode *detectCycle(ListNode *head) {
    ListNode *p1 = head, *p2 = head;
    do{
        if((p2 == 0) || (p2->next == 0)) {      //链表是有限长度的,已经走到链表尾部了,说明没有环
            return 0;
        }

        p2 = p2->next->next;         //p2一次走两步
        p1 = p1->next;//p1一次走一步
    }while(p1 != p2)

        for(p1 = head; p1 != p2; p1 = p1->next, p2 = p2->next);  //p1拉回起点,p2从相遇点开始走都是每次直走一步直到再次相遇p1就是起                                                                 //点
        return p1;
}


  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值