思路:
滑动窗口,i为左窗口,j为右窗口。
当(i,j)内无重复时,j一直右移,直至有重复j’,此时移动i,一步一步移动到重复元素后面一位(j’+1),或者直接移到(j’+1)。
代码一:HashSet O(2n)
public int lengthOfLongestSubstring(String s) {
int i=0,j=0,ans=0;
HashSet<Character> set = new HashSet<>();
while(i<s.length() && j< s.length()){
if(!set.contains(s.charAt(j))){
set.add(s.charAt(j++));
ans = Math.max(j-i,ans);
}else{
set.remove(s.charAt(i++));// 一步一步移动至重复元素后一位
}
}
return ans;
}
代码二:HashMap O(n)
public int lengthOfLongestSubstring(String s) {
int n = s.length(), ans = 0;
Map<Character, Integer> map = new HashMap<>();
int i = 0, j = 0;
for (; j < n; j++) {
if (map.containsKey(s.charAt(j))) {
i = Math.max(map.get(s.charAt(j)), i); // 直接获取该重复元素的下标,重复元素的下标会改变,所以保留最大下标
}
ans = Math.max(ans, j - i + 1);
map.put(s.charAt(j), j + 1);
}
return ans;
}