Given a linked list, determine if it has a cycle in it. Follow up: Can you solve it without using ex

题目为:Linked List Cycle

Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?

 

解法思想:

算法思想就是设置一个快指针fp和一个慢指针sp,两个指针起始同时指向head节点,其中快指针每次走两步,慢指针每次走一步,那么如果链表有环的话他们一定能够相遇。可以想象两个人同时从操场上起跑,其中甲的速度是乙速度的2倍,那么当乙跑完一圈的时候甲也跑了两圈,他们一定能够相遇

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode* pfast = head;
        ListNode* pslow = head;
        do{
            if(pfast!=NULL)
                pfast=pfast->next;
            if(pfast!=NULL)
                pfast=pfast->next;
            if(pfast==NULL)
                return false;
            pslow = pslow->next;
        }while(pfast != pslow);
        return true;
    }
};

 

为什么快指针一定要设置为慢指针的2倍

看了上面的题解也许你会问问什么快指针一定要设置为慢指针的2倍呢,为什么不是3倍。例如两个人同时从操场出发,其中甲的速度是乙的三倍,当乙跑完一圈的时候,甲跑了三圈,不也是可以相遇的吗。

接下来我会推导,设快指针fp的速度是慢指针速度sp的t倍,其他参数还和上面图片即解释一致。我们可以得出:

ts = s + nr 
->   (t-1)s = nr (3)
由(2)和(3)可以得到:
(t-1)(a+x) = nr
->  (t-1)(a+x) = (n-1)r + r
->  (t-1)(a+x) = (n-1)r + (L-a)
->  a = (n-1)/(t-1)*r + [(L-a)/(t-1) - x]
其中a必定为整数,因为a代表的是h到d的结点个数。所以(n-1)/(t-1)和(L-a)/(t-1) 也须为整数,所以当t为2的时候,一定为整数,当然t也可以为其他,只是遇到链表不一样的情况时候所得到的a不一定为整数

你可能感兴趣的:(数据结构)