1. Violence:
Ask this question let substring of a given string longest non-repeating characters, the first thought violent solution, exhaustive all substrings, and determine whether each sub-string is not repeated substring, or set the specific use hashset judge whether there is repeated characters; violence poor efficiency, time O (n ^ 3), the space O (n); reference code as follows:
1 class Solution { 2 public: 3 int lengthOfLongestSubstring(string s){ 4 int res = 0; 5 const int size = s.size(); 6 if(s.empty()) return 0; 7 if(size<=1) return size; 8 for(int i = 0;i<size;++i) 9 for(int j = i;j<size;++j) 10 { 11 int sub_seq = j-i+1; 12 if(isNoreapeatSubstring(i,j,s)){ 13 if(sub_seq>=res) 14 res = sub_seq; 15 } 16 } 17 return res; 18 } 19 20 bool isNoreapeatSubstring(int l,int h,string &s) 21 { 22 set<char> charSet; 23 for(int i =l;i<=h;i++) 24 { 25 if(charSet.find(s[i])==charSet.end()) 26 { 27 charSet.insert(s[i]); 28 } 29 else{ 30 return false; 31 } 32 } 33 return true; 34 } 35 };
2. Dynamic Programming
A little thought, it is easy to find the optimal solution of this problem is a problem of optimal substructure has, so you can use dynamic programming method;
2.1 Definitions status
dp [i]: string s, character s [i] is not the end of the repeat length of the longest substring;
2.2 Transfer transient (Equation)
If s [i] and to s [i-1] is not repeated at the end of the longest substring of characters are not all the same, dp [i] = dp [i-1] +1; otherwise, to find s [ i-1] is not repeated at the end of the longest substring and s [i] repeats the last character position index, the
dp [i] = i-1-index + 1; dynamic programming time O (n ^ 2), a space O (n ^ 2);
Reference code is as follows:
. 1 class Solution { 2 public : . 3 int lengthOfLongestSubstring ( String S) { . 4 const int size = s.size (); . 5 IF (s.empty ()) return 0 ; . 6 IF (size <= . 1 ) return size; . 7 int DP [size]; // DP [I] indicated by s [i] is not repeated at the end of the substring . 8 Memset (DP, 0 , size); . 9 int RES = . 1 ; 10 DP [ 0]=1;//dp初始值 11 for(int i = 1;i<size;++i) 12 { 13 bool reapeat = false; 14 int index = 0; 15 for(int j = i-1;j>= i-1-dp[i-1]+1;j--) 16 { 17 if(s[j]==s[i]) 18 { 19 reapeat = to true ; 20 is index = J; // recent repeated 21 is BREAK ; 22 is } 23 is } 24 IF (reapeat) // repeat 25 { 26 is DP [I] = I- . 1 -index + . 1 ; 27 } 28 the else // not repeat 29 { 30 DP [I] DP = [I- . 1 ] + . 1 ; 31 is } 32 IF(dp[i]>=res) 33 res=dp[i]; 34 } 35 return res; 36 } 37 };
3. The sliding window + hash table method
May maintain a sliding window as they traverse the string so that substring within a string that represents the current sliding window will not be repeated longest substring, in particular, the use of character string records hashmap m and location of the last occurrence mapping between; defined variables left, res, left represents the left edge of the previous location of the sliding window, is initialized to -1, res represents the maximum length of the sliding window;
When traversing a character s [i], if the position of the character in the hashmap, and the last in the sliding window (i> left), the right boundary of the sliding window, left = m [s [i]]; and update hash table,
+ Using a sliding window method of the hash table can be achieved best efficiency, since only traversed again, the time O (n), because the number of characters is constant (up to 128) all space O (1),
class Solution { public : int lengthOfLongestSubstring ( String S) { int RES = 0 , left = - . 1 , str_len s.size = (); // unordered_map < int , int > m; // map character and its last character to appear for ( int I = 0 ; I <str_len; ++ I) { IF (m.count (S [I]) && m [S [I]]> left) { left = m [S [I]] ; } m [S [I]] = I; // location updating last occurrence of the character res = max(res,i-left); } return res; } };
The wording of the above solution is below Lite mode, where we can establish a 256-bit integer array size instead of HashMap, the reason for this is the ASCII table can represent a total of 256 characters, but because the keyboard can only represent 128 characters so also with the 128 line, then all initialized to -1, this benefit is not like before, like HashMap current character you want to find whether there is a mapping for each character to traverse, with its direct value in the array to update the left, because the default is -1, and left initialization is -1, and hence does not generate an error, thus saving steps if the judge, and the rest are the same ideas:
class Solution { public: int lengthOfLongestSubstring(string s) { vector<int> m(128, -1); int res = 0, left = -1; for (int i = 0; i < s.size(); ++i) { left = max(left, m[s[i]]); m[s[i]] = i; res = max(res, i - left); } return res; } };