Two kinds of sentence and brent circle method --floyd

This thing is actually quite naive.

floyd sentenced circle

It is probably the fast and slow pointer to pointer \: (12 \) forward speed.
When the fast and slow pointer pointer meet again, the difference is a certain distance they travel the length of the loop integral multiple.
Why?
Consider the general situation is taking a backward chain of a circle.
Provided a chain length of \ (m \) , lap length \ (n-\) , slow down the pointer \ (A \) ring, the pointer quickly go \ (B \) ring, they encounter the next lap distance into punctuate \ (D \) position, then
\ [s = m + n *
a + d \\ 2s = m + n * b + d \\ \] to give \ (dif = s = n * (a - b) \ ) , there \ (the n-| DIF \) .
Consideration of the above-described simulation procedure stopped when two pointers meet again.
At this time, the slow movement of the pointer to the original node, the pointer does not move quickly to \: (11 \) speed move.
Because of \ (m + d = n ( b - 2a) \) i.e. \ (n-| (m + D) \) , think about the speed of the pointer found in the punctuate necessarily meet (at this time go slower pointer \ (m \) , the pointer from the fast punctuate \ (d + m \)In die \ (n-\) in the sense exactly \ (0 \) ).
The whole process can be simulated by \ (\ mathcal O (m + n) \) time of the answer.

int *h = head, *t = head;
do {
    h = h->next;
    if (h != null) {
        h = h->next;
    }
    t = t->next;
} while (h != t || h != null);
if (h != null) {
    t = head;
    while (h != t) {
        h = h->next;
        t = t->next;
    }
    p = h;
}

brent sentenced circle

Began to make the speed of the pointer to the starting node, so slow pointers remain intact, fast hands go \ (2 ^ i \) steps. After the fast hand every step, it is determined whether the speed of the pointer met. If you go \ (2 ^ i \) does not meet the step, it will slow the pointer position to fast-pointer at, and \ (i ++ \) ; otherwise find the circle, exit. Complexity with Floyd (constant smaller).

int *t = head, *h = head;
int s = 0, lim = 2;
while (1) {
    if (h == null) {
        // no loop
        break;
    }
    ++s;
    if (h == t) {
        // find loop
        break;
    }
    if (s == lim) {
        s = 0;
        lim <<= 1;
        t = h;
    }
}

Guess you like

Origin www.cnblogs.com/psimonw/p/11697526.html