Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "ABCABCBB" are "abc", which the length is 3. For "bbbbb" the longest substring are "B", with the length of 1.
Solution One: Enumerate all substrings of a string, remove the part with repeated characters, and finally find the longest one. The stupidest way, Time complexity O (n^4).
intMax_unique_substring1 (Char*str) { intMaxLen =0; intBegin =0; intn =strlen (str); for(intI=0; i<n; ++i) for(intj=1; j<n; ++j) {intFlag =0; for(intM=i; m<=j; ++m) { for(intn=m+1; n<j; ++N) {if(Str[n] = =Str[m]) {Flag=1; Break; } } if(Flag = =1) Break; } if(flag==0&& j-i+1>maxlen) {MaxLen= j-i+1; Begin=i; }} printf ("%.*s\n", MaxLen, &Str[begin]); returnMaxLen;}
Solution Two: The test substring of the solution one is "no repeating character" to improve, using the hash table to record whether the character has occurred, the time complexity is reduced to O (n^2).
intMax_unique_substring2 (Char*str) { inti,j; intbegin; intMaxLen =0; inthash[ the]; intn =strlen (str); for(i=0; i<n; ++i) {memset (hash,0,sizeof(hash)); Hash[str[i]]=1; for(j=i+1; j<n; ++j) {if(Hash[str[j]] = =0) Hash[str[j]]=1; Else Break; } if(J-i >maxlen) {MaxLen= Ji; Begin=i; }} printf ("%.*s\n", MaxLen, &Str[begin]); returnMaxLen;}
Solution three: For the string "Axbdebpqawuva", the following table is constructed:
Table, the string has 3 ' a ', has 2 ' B ', and the remainder is a single character. Next[] records the position of the next duplicate character, such as str[0]=str[8]=str[12]= ' a ', at which point Next[0]=8,next[8]=12,next[12]=13, the rest of the same. It is worth noting that next[] stores the subscript for the character Terminator ' \ s ', i.e. 13, for non-repeating characters.
Here, First[i] represents the position after I, where the repetition character first appears. For example, Str[0], the first occurrence of the repeating character is str[5]= ' B ', of course, starting from str[1],str[2]. The repeat character ' a ' will appear to str[12] starting from str[3]. It can be proved that the length of the longest meeting requirement from str[i] is first[i]-i, and the interval is [i,first[i]-1] to be solved. The longest string above is when i=3, first[i]-i=12-3=9. The result string is DEBPQAWUV.
//time complexity of O (N)intMax_unique_substring3 (Char*str) { intMaxLen =0; intBegin =0; intn =strlen (str); int* Next = (int*)malloc(sizeof(int) *n);//Next[i] Record the position of the next character that repeats with Str[i] int* First = (int*)malloc(sizeof(int) * (n+1));//First[i] Records the most recent repetition point after Str[i] inthash[ the]; memset (Hash,n,sizeof(hash)); First[n]=N; for(inti=n-1; i>=0; i--) {Next[i]=Hash[str[i]]; Hash[str[i]]=i; if(Next[i] < first[i+1]) First[i]=Next[i]; ElseFirst[i]= first[i+1];//generates a first[] table with the complexity of O (N) } for(intI=0; i<n; i++) { if(First[i]-i >maxlen) {MaxLen= first[i]-i; Begin=i; } } Free(first); Free(next); printf ("%.*s\n", MaxLen, &Str[begin]); returnMaxLen;}
Solution four: Using a suffix array
Construct the suffix array for this string, and in each suffix array, look for the longest prefix with no repeating characters, and the longest prefix is the substring to be searched.
//get the longest non-repeating prefix length of the stringintLongestlen (Char*p) { inthash[ the]; intLen =0; memset (Hash,0,sizeof(hash)); while(*p &&!hash[*P]) {hash[*P] =1; ++Len; ++p; } returnLen;}//using the suffix array solutionintMax_unique_substring4 (Char*str) { intMaxLen =-1; intBegin =0; Char*a[99999]; intn =0; while(*str! =' /') {A[n+ +] = str++; } for(intI=0; i<n; i++) { intTemlen =Longestlen (A[i]); if(Temlen >maxlen) {MaxLen=Temlen; Begin=i; }} printf ("%.*s\n", MaxLen, A[begin]); returnMaxLen;}
Solution Five: We create an integer array of 256-bit size instead of a hash table, because the ASCII table is capable of representing 256 characters, so all characters can be recorded, and then we need to define two variables res and left, where Res is used to record the length of the longest no-repeat substring, Left points to the beginning of the leftmost substring, and then we traverse the entire string, and for each character traversed, if the string corresponds to a value of 0 in the hash table, indicating that the character has not been encountered, the longest non-repeating substring, i-left +1, is calculated at this time. Where I is the longest non-repeating substring of the rightmost position, left is the leftmost position, there is a situation also need to calculate the longest non-repeating substring, that is, when the value of the hash table is less than left, this is because there are repeated characters, the location of the last update, if you encounter new characters, It is necessary to recalculate the longest non-repeating substring. Finally, each time you assign the value of the current character to I+1 in the Hashtable.
Explain the next procedure in the IF condition statement why have a m[s[i]] < Left, we use an example to illustrate, when the input string is "ABBCA" when the i=4, that is, is about to start to traverse the last letter a, the hash table in a corresponding to the 1,b corresponding to 3, C corresponds to 4,left 2, that is, the left edge of the current longest substring is the position of the second B, and the first A is not in the range of the current longest string, then for i=4 this new incoming A, should be added to the result, and at this time not updated hash table in a is 1, not 0, If you do not judge the relationship between it and left, you can not update the results, then the answer will be one less, so need to add m[s[i]] < left.
classSolution { Public: intLengthoflongestsubstring (strings) {intm[ the] = {0}, res =0, left =0; for(inti =0; I < s.size (); ++i) {if(M[s[i]] = =0|| M[s[i]] <Left ) {Res= Max (res, I-left +1); } Else{ Left=M[s[i]]; } M[s[i]]= i +1; } returnRes; }};
[Leetcode] 3. Longest Substring without repeating characters look for substrings with the longest no repetition character