This seems simple. It is to store a hash table <char, character location> and traverse the entire string in sequence. When there are previous characters, you should stop the current count, the new substring starts from the next position where the character is located.
I started to write a simple writing method and found that it timed out:
if (s.empty())return 0;if (s.length() == 1)return 1;int longest = 1;for (int i = 0; i < s.length(); i++){int len = 0;unordered_map<char, int> substr;int index = i;while (i < s.length() && (substr.find(s[i]) == substr.end() || substr.find(s[i])->second == index) ){if (substr.find(s[i]) == substr.end()){substr[s[i]] = i;len++;}else {substr[s[i]] = i;}i++;}if (len > longest)longest = len;if (i < s.length()){i = substr.find(s[i])->second + 1;}//i = index;}return longest;
The problem here is that when we find repeated characters, the string pointer should not be traced back, which is a waste!
In fact, you only need to modify the start position of the string. In addition, the hash table must store the rightmost position of a character at any time.
int lengthOfLongestSubstring(string s) { if (s.empty()) return 0; if (s.length() == 1) return 1; unordered_map<char, int> charIndex; int start = 0; int longest = 1; int len = 1; charIndex[s[0]] = 0; for (int i = 1; i < s.length(); i++){ if (charIndex.find(s[i]) == charIndex.end()){ charIndex[s[i]] = i; len++; } else{ if (charIndex[s[i]] > start){ if (len > longest) longest = len; len -= charIndex[s[i]] - start; start = charIndex[s[i]] + 1; } else if (charIndex[s[i]] == start){ start += 1; } else { len++; } charIndex[s[i]] = i; } } if (len > longest) longest = len; return longest; }
Longest substring without repeating characters