Given a string s, find the length of the longestsubstring without duplicate characters.
Example 1:
Input: s = "abcabcbb"
Output: 3
Explanation: The answer is "abc", with the length of 3. Note that "bca" and "cab" are also correct answers.
Example 2:
Input: s = "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.
Example 3:
Input: s = "pwwkew"
Output: 3
Explanation: The answer is "wke", with the length of 3.
Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.
Constraints:
0 <= s.length <= 105
s consists of English letters, digits, symbols and spaces.
Solutions
Solution 1: Sliding Window
Thinking
The first idea is to try every substring and test uniqueness. Correct, but at least \(O(n^2)\). \(n \le 10^5\) will time out.
The waste is overlap: once \([l,r]\) has no repeats, adding a character \(c\) on the right only needs to fix whether \(c\) broke the window—not a full rescan.
A duplicate means the valid answer cannot keep the extra \(c\) on the left, so \(l\) must move right. A count table telling whether \(\textit{cnt}[c] > 1\) is enough to decide shrinking; after \(c\) appears once, the window is the longest unique substring ending at \(r\).
We can use two pointers \(l\) and \(r\) to maintain a sliding window that always satisfies the condition of having no repeating characters within the window. Initially, both \(l\) and \(r\) point to the first character of the string. We use a hash table or an array of length \(128\) called \(\textit{cnt}\) to record the number of occurrences of each character, where \(\textit{cnt}[c]\) represents the number of occurrences of character \(c\).
Next, we move the right pointer \(r\) one step at a time. Each time we move it, we increment the value of \(\textit{cnt}[s[r]]\) by \(1\), and then check if the value of \(\textit{cnt}[s[r]]\) is greater than \(1\) within the current window \([l, r]\). If it is greater than \(1\), it means there are repeating characters within the current window, and we need to move the left pointer \(l\) until there are no repeating characters within the window. Then, we update the answer \(\textit{ans} = \max(\textit{ans}, r - l + 1)\).
Finally, we return the answer \(\textit{ans}\).
The time complexity is \(O(n)\), where \(n\) is the length of the string. The space complexity is \(O(|\Sigma|)\), where \(\Sigma\) represents the character set, and the size of \(\Sigma\) is \(128\).