给定一个字符串 s ,请你找出其中不含有重复字符的  **最长子串  **的长度。
示例  1:
**输入:** s = "abcabcbb"
**输出:** 3 
**解释:** 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
**输入:** s = "bbbbb"
**输出:** 1
**解释:** 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
**输入:** s = "pwwkew"
**输出:** 3
**解释:** 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 **子串** 的长度,"pwke" 是一个 _子序列,_ 不是子串。
提示:
0 <= s.length <= 5 * 104 
s 由英文字母、数字、符号和空格组成 
思路:
这道题主要用到思路是:滑动窗口
什么是滑动窗口?
其实就是一个队列,比如例题中的 abcabcbb,进入这个队列(窗口)为 abc 满足题目要求,当再进入 a,队列变成了 abca,这时候不满足要求。所以,我们要移动这个队列!
如何移动?
我们只要把队列的左边的元素移出就行了,直到满足题目要求!
一直维持这样的队列,找出队列出现最长的长度时候,求出解!
时间复杂度:$O(n)$
代码:
[1]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | class Solution:     def lengthOfLongestSubstring(self, s: str) -> int:         if not s:return 0         left = 0         lookup = set()         n = len(s)         max_len = 0         cur_len = 0         for i in range(n):             cur_len += 1             while s[i] in lookup:                 lookup.remove(s[left])                 left += 1                 cur_len -= 1             if cur_len > max_len:max_len = cur_len             lookup.add(s[i])         return max_len
   | 
  
[1]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
   | class Solution { public:     int lengthOfLongestSubstring(string s) {         if(s.size() == 0) return 0;         unordered_set<char> lookup;         int maxStr = 0;         int left = 0;         for(int i = 0; i < s.size(); i++){             while (lookup.find(s[i]) != lookup.end()){                 lookup.erase(s[left]);                 left ++;             }             maxStr = max(maxStr,i-left+1);             lookup.insert(s[i]);     }         return maxStr;              } };
  | 
  
[1]1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
   | class Solution {     public int lengthOfLongestSubstring(String s) {         if (s.length()==0) return 0;         HashMap<Character, Integer> map = new HashMap<Character, Integer>();         int max = 0;         int left = 0;         for(int i = 0; i < s.length(); i ++){             if(map.containsKey(s.charAt(i))){                 left = Math.max(left,map.get(s.charAt(i)) + 1);             }             map.put(s.charAt(i),i);             max = Math.max(max,i-left+1);         }         return max;              } }
  | 
  
下面介绍关于滑动窗口的万能模板,可以解决相关问题,相信一定可以对滑动窗口有一定了解!
模板虽好,还是少套为好!多思考!更重要!
还有类似题目有:
3. 无重复字符的最长子串 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
   | class Solution:     def lengthOfLongestSubstring(self, s):         """         :type s: str         :rtype: int         """         from collections import defaultdict         lookup = defaultdict(int)         start = 0         end = 0         max_len = 0         counter = 0         while end < len(s):             if lookup[s[end]] > 0:                 counter += 1             lookup[s[end]] += 1             end += 1             while counter > 0:                 if lookup[s[start]] > 1:                     counter -= 1                 lookup[s[start]] -= 1                 start += 1             max_len = max(max_len, end - start)         return max_len
   | 
 
 76. 最小覆盖子串 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
   | class Solution:     def minWindow(self, s: 'str', t: 'str') -> 'str':         from collections import defaultdict         lookup = defaultdict(int)         for c in t:             lookup[c] += 1         start = 0         end = 0         min_len = float("inf")         counter = len(t)         res = ""         while end < len(s):             if lookup[s[end]] > 0:                 counter -= 1             lookup[s[end]] -= 1             end += 1             while counter == 0:                 if min_len > end - start:                     min_len = end - start                     res = s[start:end]                 if lookup[s[start]] == 0:                     counter += 1                 lookup[s[start]] += 1                 start += 1         return res
   | 
 
159. 至多包含两个不同字符的最长子串 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | class Solution:     def lengthOfLongestSubstringTwoDistinct(self, s: str) -> int:         from collections import defaultdict         lookup = defaultdict(int)         start = 0         end = 0         max_len = 0         counter = 0         while end < len(s):             if lookup[s[end]] == 0:                 counter += 1             lookup[s[end]] += 1             end +=1             while counter > 2:                 if lookup[s[start]] == 1:                     counter -= 1                 lookup[s[start]] -= 1                 start += 1             max_len = max(max_len, end - start)         return max_len
   | 
 
 340. 至多包含 K 个不同字符的最长子串 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
   | class Solution:     def lengthOfLongestSubstringKDistinct(self, s: str, k: int) -> int:         from collections import defaultdict         lookup = defaultdict(int)         start = 0         end = 0         max_len = 0         counter = 0         while end < len(s):             if lookup[s[end]] == 0:                 counter += 1             lookup[s[end]] += 1             end += 1             while counter > k:                 if lookup[s[start]] == 1:                     counter -= 1                 lookup[s[start]] -= 1                 start += 1             max_len = max(max_len, end - start)         return max_len
   | 
 
滑动窗口题目:
3. 无重复字符的最长子串 
 30. 串联所有单词的子串 
 76. 最小覆盖子串 
159. 至多包含两个不同字符的最长子串 
 209. 长度最小的子数组 
239. 滑动窗口最大值 
567. 字符串的排列 
 632. 最小区间 
 727. 最小窗口子序列