Sliding Window
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Solution { public int lengthOfLongestSubstring(String s) { int maxLength = 0;
int[] windowMap = new int[256]; int i = 0; for (int j = 0; j < s.length(); j++) { char c = s.charAt(j); windowMap[c]++;
while (windowMap[c] > 1) { char leftmost = s.charAt(i); windowMap[leftmost]--; i++; }
maxLength = Math.max(maxLength, j - i + 1); }
return maxLength; } }
|
此解法为添加至窗口后再移除重复元素。
Sliding Window
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { public int lengthOfLongestSubstring(String s) { int maxLength = 0;
boolean[] windowMap = new boolean[256]; int i = 0; for (int j = 0; j < s.length(); j++) { char c = s.charAt(j); while (windowMap[c]) { char leftmost = s.charAt(i); windowMap[leftmost] = false; i++; }
windowMap[c] = true; maxLength = Math.max(maxLength, j - i + 1); }
return maxLength; } }
|
此解法为添加至窗口前移除重复元素,相比上方解法,此解法可使用 boolean 数组,更节省空间。
Sliding Window
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 { public int lengthOfLongestSubstring(String s) { int maxLength = 0; Map<Character, Integer> valueToPrevIndexMap = new HashMap<>();
int i = 0; for (int j = 0; j < s.length(); j++) { char c = s.charAt(j); Integer prevIndex = valueToPrevIndexMap.get(c); if (prevIndex != null) { i = Math.max(i, prevIndex + 1); }
valueToPrevIndexMap.put(c, j); maxLength = Math.max(maxLength, j - i + 1); }
return maxLength; } }
|
此解法中的 HashMap 持有的为遍历过的元素与索引的映射,遍历过程中不会移除映射,因为该解法中途不移除映射,导致对 i 的更新需要使用 Math.max 保证 i 只能增大。
References
3. Longest Substring Without Repeating Characters
剑指 Offer 48. 最长不含重复字符的子字符串
剑指 Offer II 016. 不含重复字符的最长子字符串