First Thought: Let I point to the first end of the string, J points to the end, and then gradually decline for each I, j, and then judge whether the string I to J is a return to the text. This idiot's idea requires O (N3) time at the worst. Although it can be done through local optimization, I and j traversal and retrieval judgment can be completed in advance, however, the eighth test data cannot survive. It takes more than two minutes to complete. It takes more than four seconds to run on the local machine. I will try again!
I searched the internet and showed that my idea was to move closer from both sides to the center. In fact, I could also extend from the center to both sides. In this way, I only need to traverse each center and perform a two-way search for each center, the time complexity is reduced to O (n2), which is acceptable. The symmetric positions of Abba and abcba are different in two cases...
In actual coding, it is much easier to implement than the original idea, with fewer cyclic boundary conditions and lower chance of errors, it took a day to submit the last te and Wa seven times!
Another way on the Internet is to flip the input string and find the longest public substring. This is not detailed. Let's talk about it later...
/* <Br/> ID: <br/> LANG: C <br/> task: calfflac <br/> */<br/> # include <stdio. h> <br/> # include <stdlib. h> <br/> # include <ctype. h> <br/> # define sz20000 <br/> int has_pal (char * txt, int Len, int * low, int * High) {<br/> int n = 0; <br/> int I = * low; <br/> Int J = * high; <br/> If (* High-* low = 2 & isalpha (txt [* High-1]) // contribute wa once! <Br/> n = 1; <br/> while (* low> = 0 & * High <Len) {<br/> If (! Isalpha (txt [* low]) {<br/> (* low) --; <br/> continue; <br/>}< br/> If (! Isalpha (txt [* High]) {<br/> (* High) ++; <br/> continue; <br/>}< br/> If (tolower (txt [* low]) = tolower (txt [* High]) {<br/> I = * low; <br/> J = * high; <br/> (* low) --; <br/> (* High) ++; <br/> N + = 2; <br/>}< br/> else break; <br/>}< br/> * low = I; <br/> * High = J; <br/> return N; <br/>}< br/> int main () {<br/> file * fin = fopen ("calfflac. in "," R "); <br/> file * fout = fopen (" calfflac. out "," W "); <br/> char C, TXT [SZ]; <Br/> int I, j, k, n, txt_len; <br/> int low, high, pal_len; <br/> for (I = 0; (C = fgetc (FIN ))! = EOF; I ++) <br/> TXT [I] = C; <br/> txt_len = I; <br/> low = high = pal_len = 0; <br/> for (k = 0; k <txt_len-1; k ++) {<br/> I = K; <br/> J = k + 1; <br/> N = has_pal (txt, txt_len, & I, & J); // even <br/> If (n> pal_len) {<br/> low = I; <br/> high = J; <br/> pal_len = N; <br/>}< br/> I = k-1; <br/> J = k + 1; <br/> N = has_pal (txt, txt_len, & I, & J ); // odd <br/> If (n> pal_len) {<br/> low = I; <br/> high = J; <br/> pal_len = N; <br/>}< br/> fprintf (fout, "% d/N", pal_len); <br/> for (; low <pigh; low ++) <br/> fprintf (fout, "% C", TXT [low]); <br/> fprintf (fout, "% C/N ", TXT [High]); <br/> exit (0); <br/>}< br/>
The basic idea of the analysis solution is the same as mine, but the implementation is slightly different. It stores the input string in two arrays, one of which is the original array, one is a plain text array that removes punctuation spaces, then uses the last array to find the length of the longest return string, and then outputs the entire return string in the original array...
This question has taught me a lot:
1. Do not rely too much on test cases. Think of all possible situations as much as possible. The feeling of being beaten back every time you submit the case is rather bad, and the enthusiasm is severely affected...
2. When constructing an algorithm, you must think of the limit and design an algorithm that can withstand the test. It is not a trivial matter that the time complexity is too high !!
3. Broaden your thinking and think more about it. Don't ask Google if you have any problems. Are you so eager to get a new one ?!