LeetCode: Linked List Cycle II

Q:Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

Follow up:
Can you solve it without using extra space?

A: We put two points to traverse the linked list. P1 takes one step, P2 takes two step. If where is a cycle in the list , these two points will meet each other undoubtedly(see: http://blog.csdn.net/tuntunwork/article/details/38871493).

  Then put two point on the linked list, one point is at the begin of the linked list , the other point is at the point where P1 and P2 meet each other. When there two points meet each other, the place is the node where the cycle begins.


Proof: We assume these is cycle in the linked list. When P1 and P2 meet each other, P1 has not traversed the whole cycle. We assume P1 has already traversed s nodes, then P2 has already traversed 2s nodes. At this time, P2 has taken more n*r steps than P1(r is the circumference of the cycle).

s + n*r = 2s

s = n*r

We assume the distance between the head of linked list and the begin of the cycle is a. And the distance between the begin of the cycle and the node where P1 and P2 meet each other is x. The length of the linked list is L.

L = a + r

a + x = s (the length which P1 has already traversed)

a + x = n * r = (n-1)*r + r = (n-1)*r + L - a

a = (n-1)*r + (L - a -x)

a%r = (L-a-x)%r

a is the distance between the head and the begin of the cycle.

L-a-x is the distance between the begin of the cycle and the node where P1 and P2 meet each other.

Based on the proof above, when P3 is at the head of the list , P4 is at the node where P1 and P2 meet each other, P3 and P4 take one step each time, the palce where P3 and P4 meet each other is the begin of the cycle(a).

ListNode *detectCycle(ListNode *head) {
        if(NULL == head)
            return NULL;
        if(NULL == head->next)
            return NULL;
        if(NULL == head->next->next){
            if(head == head->next->next){
                return head;
            }
            return NULL;
        }
        ListNode* slow = head->next;
        ListNode* fast = head->next->next;
        while(NULL != fast && NULL != fast->next){
            if(slow == fast)
                break;
            else{
                slow = slow->next;
                fast = fast->next->next;
            }
        }
        if(NULL == fast || NULL == fast->next){
            return NULL;
        }
        slow = head;
        while(fast != NULL){
            if(slow == fast){
                return slow;
            }
            slow = slow->next;
            fast = fast->next;
        }
        return NULL;
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值