Problem description: a string of beads (n) connected at the beginning and end, with N colors (n <= 10). design an algorithm and extract one of them, which must contain N colors, and minimize the length. Analyze the time complexity and space complexity.
Idea: a counting method can be used. Define two pointers, P1 and P2. There are three steps:
(1) When P1 moves forward, if the color number of the beads referred to by P1 is I, the number of occurrences of I is increased. When the number of colors is N, P1 is stopped.
(2) P2 moves forward. If P2 refers to the beads with the color number I, the number of occurrences of I is reduced. P2 stops when the number of colored species decreases to N-1.
(3) The beads referred to by P1 and P2 contain N colors. If it is shorter than the current minimum segment, update it. Return to (1) continue. The cycle termination condition is P2 pointing to the last bead.
The above provides implementation ideas. Pay attention to the specific implementation. This beaded should be ring-shaped. The time complexity is O (n), and the space complexity is O (n ).
Reference code:
Const int n = 5; // color type // function: Find the target bead. The color of the bead is represented by a number. // function parameter: pbead points to the bead array. N indicates the number of beads, from is the start position, to is the end position // return value: true; otherwise, false bool beadproblem (int * pbead, int N, Int & from, Int &) {If (pbead = NULL | n <n) return false; // The parameter is faulty. Int count [N] = {0} cannot be found }; // used to count int minlen = n + 1; int I = 0, j =-1, CNT = 0; while (j <n-1) // J = n-1, point to the last bead {If (++ count [pbead [I] = 1 & + CNT = N) // Step 1 {for (j = J + 1; j <n & -- cou NT [pbead [J]; j ++) // Step 2; If (j = N) j --; // the last position has been crossed, step back // step 3int Len = (j> I )? I-j + 1 + N: I-j + 1; // length calculation formula if (LEN <minlen) // update the length and start position {to = I; from = J; minlen = Len;} CNT --; // The number of colors minus 1} I = (I + 1) % N; // considering the characteristics of the ring, it cannot be I ++ if (I = 0 & J =-1) // I returns to the initial position, but J is not updated, that is, the qualified segment break is not found;} return minlen! = N + 1 ;}
There are several points to explain: first, the judgment statement if (++ count [pbead [I] = 1 & + + CNT = N) seems complicated. Specifically, increase the appearance of the current bead color. If not 1, based on the Boolean short circuit principle, ++ CNT
Not executed. If it is 1, it indicates that the first occurrence requires an increase in the number of colors that appear, So execute ++ CNT. If CNT is increased to n, a bead is found, containing N colors. Then enter the if statement to shorten it as much as possible.
Second, for (j = J + 1; j <n & -- count [pbead [J]; j ++. Why does J Add 1 at the beginning? It can be understood that, assuming that a piece of beads has been found, J points to the end of the beads. Now again, the end of the bead should start from J + 1 and should not contain J.
The following is a test procedure and some test results.
Int main () {int bead [] = {3, 3,}; int from, to; int n = sizeof (bead) /sizeof (INT); If (beadproblem (bead, N, from, to) {int I; for (I = from; I! = To; I = (I + 1) % N) cout <bead [I] <''; cout <bead [I] <Endl ;} return 0;} // Input and Output // {, 4} {, 4,, 4} {, 1, 2, 0} // {, 4, 3,4,} {, 1} // {, 4} cannot be found
I enjoy the copyright of blog articles, reprint please indicate the source http://blog.csdn.net/wuzhekai1985