3. 无重复字符的最长子串 (最长子串 滑动窗口)
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given "abcabcbb"
, the answer is "abc"
, which the length is 3.
Given "bbbbb"
, the answer is "b"
, with the length of 1.
Given "pwwkew"
, the answer is "wke"
, with the length of 3. Note that the answer must be a substring, "pwke"
is a subsequence and not a substring.
class Solution: def lengthOfLongestSubstring(self, s: str) -> int: left = right = res = 0 dd = collections.defaultdict(int) n = len(s) while right < n: ch = s[right] dd[ch]+=1 right+=1 while dd.get(ch,0) > 1: dd[s[left]]-=1 left+=1 res = max(res,right-left) return res
class Solution { public: int lengthOfLongestSubstring(string s) { int left = 0; int right = 0; int res = 0; unordered_map<char,int> char_map; while(right < s.size()) { char cur_c = s[right]; char_map[cur_c]++; right++; while(char_map[cur_c]>1) { char cur_c = s[left]; char_map[cur_c]--; left++; } res = max(res,right-left); } return res; } };
暴力:时间0(n2)
空间o(n)
1 class Solution { 2 public: 3 int lengthOfLongestSubstring(string s) { 4 const int n = s.size(); 5 std::unordered_set<char> s_set; 6 int res = 0; 7 for (int i = 0; i < n; i++) { 8 int j = i; 9 s_set.clear(); 10 for (; j < n ;++j) { 11 if (s_set.find(s[j])==s_set.end()) { 12 s_set.emplace(s[j]); 13 } else { 14 break; 15 } 16 } 17 res = std::max(res,j-i); 18 } 19 return res; 20 } 21 };
1 class Solution { 2 public: 3 int lengthOfLongestSubstring(string s) { 4 const int n = s.size(); 5 std::unordered_set<char> s_set; 6 int res = 0; 7 int j = 0; 8 for (int i = 0; i < n;++i) { 9 while(s_set.find(s[i])!=s_set.end()) { 10 s_set.erase(s[j]); 11 j++; 12 } 13 res = std::max(res,i-j+1); 14 s_set.emplace(s[i]); 15 } 16 return res; 17 } 18 };
这个题的关键在于重复的字符!
一个子串不可能出现重复的字符,那么我们可以用两个指针,一个指针用来遍历字符串,两个指针之间保持无重复字符,那么两个指针之间的长度即最大子串的长度。当发现有重复的字符时,另一个指针指向这个字符上一次出现的位置的下一个字符,继续遍历,直到找到最长子串。
1 class Solution: 2 def lengthOfLongestSubstring(self, s): 3 """ 4 :type s: str 5 :rtype: int 6 """ 7 j = 0 8 maxlen = 0 9 used ={} 10 for i ,c in enumerate(s): 11 if c not in used or used[c] < j: 12 maxlen = max(maxlen,i-j + 1) 13 else: 14 j = used[c] + 1 15 used[c] = i 16 return maxlen
代码中:
used[c] < start 是为了处理"tmmzuxt" 这种连续出现的2个字母。