Linked List Cycle II

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        // IMPORTANT: Please reset any member data you declared, as
        // the same Solution instance will be reused for each test case.
        if(head==NULL)return NULL;
        if(head->next==NULL)return NULL;
        if(head->next->next==NULL)return NULL;
        ListNode *pre = head->next;
        ListNode *nxt = pre->next;
        while(1){
            if(pre==nxt)break;
            if(pre->next==NULL)return NULL;
            pre = pre->next;
            if(nxt->next==NULL)return NULL;
            nxt = nxt->next;
            if(nxt->next==NULL)return NULL;
            nxt = nxt->next;
        }
        pre = head;
        while(pre!=nxt){
            pre = pre->next;
            nxt = nxt->next;
        }
        return pre;
    }
};

对于判断链表是否有环,方法很简单,用两个指针,一开始都指向头结点,一个是快指针,一次走两步,一个是慢指针,一次只走一步,当两个指针重合时表示存在环了。

证明:假设链表有环,环的长度为N,慢指针在起始位置,快指针在位置k(位置从0开始计数),那么快指针只要比慢指针多走经过N-k步,就可以追上慢指针了。。。,因为每一次快指针都比慢指针多走一步,所以一定可以在有限的步数追上慢指针。

那么如何求环的起点呢:

1.假设我们的slow走了x步到达环的起点。

2.再走m步与fast汇合,那么这时,fast走的步数为2m+2x

3.同时fast在环中走的步数为2m+x;

4,所以可得2m+x=m+in(n为环的长度 )

所以可得m+x=in;

slow 移到head再走 x后。

注意:此时我们让fast指针也变成每次走一步

到达了开始,而此时fast的位置是2m+x+x

所以此时fast也走到了开始位置


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值