Window size is not fixed. Expand right to grow; when constraint violated, shrink from left until valid again. Track the best window seen.
Each element is processed at most twice (once by R, once by L). The map holds at most k unique elements where k = alphabet size or distinct elements.
For ASCII strings: effectively O(1) space since k ≤ 128.
int longestSubstringNoRepeat(String s) { int left = 0, result = 0; Map<Character, Integer> window = new HashMap<>(); for (int right = 0; right < s.length(); right++) { // ① EXPAND — add s[right] into window window.merge(s.charAt(right), 1, Integer::sum); // ② SHRINK — while duplicate exists, remove from left while (window.get(s.charAt(right)) > 1) { window.merge(s.charAt(left), -1, Integer::sum); if (window.get(s.charAt(left)) == 0) window.remove(s.charAt(left)); left++; } // ③ UPDATE — record best window length result = Math.max(result, right - left + 1); } return result; // O(n) — each char enters and exits at most once }