环形链表2(C++)

 思路分析:

与环形链表1一样,我们需要定义慢指针和快指针,确定链表是否有环,如果链表没有环的话,直接置空即可。如果链表有环,则需要向环形链表1一样,让快指针不断追赶慢指针,找到恰好追上的结点。

本题如果想找到开始入环的第一个结点,则需要用到一个结论:定义两个新指针,一个从头开始走,一个从慢指针和快指针相遇的地方开始走,两者恰好在链表开始入环的地方相遇。

以下是证明过程:

 如图所示,设从开始到入环的距离为L,入环到两者相遇的距离为X,慢指针走的路程为L+X,快指针走的路程为L+X+N*C(C代表环的长度),因为快指针有可能在环中走了N圈,所以这段路程要加上。由于快指针的速度是慢指针的2倍,路程也是二倍,所以有等式2*(L+X)=L+X+N*C,整理得L=C*N-X,再变形得L=C*(N-1)+C-X,说明L的长度和C-X的长度相等,只不过有可能差来N圈,由而得出上面的结论。

代码的实现按照上面的结论即可。

代码如下:

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* slow, * fast;
      ListNode* meet=NULL;
      ListNode* cur = NULL;
      slow = fast = head;
      while (fast && fast->next)
      {
          slow = slow->next;
          fast = fast->next->next;
          if (slow == fast)
          {
              meet = slow;
              cur = head;
          while (cur != meet)
          {
              meet = meet->next;
              cur = cur->next;
          }
          return cur;
          }
      }
      return NULL;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值