思想: 采用滑动窗口思想,利用Map来实现一个窗口,每扩充一下窗口就去更新结果res 需要特别注意的是在扩充窗口时需注意:如果map中不包含right所指向的字符,直接扩充即可;但是如果map中包含right所指向的字符,此时就有可能需要右移left指针,区分到底是否需要右移left指针需要区分到底是因为跟当前窗口之前(外)的字符重复,还是跟当前窗口内的元素重复。如果是因为跟当前窗口之前(外)的字符重复,而不是跟当前窗口内的元素重复,那么此时left还是指向当前窗口的left(也就是此时Math.max(left,map.get(c)+1) = left ),否则就指向发生重复的下一个位置(此时Math.max(left,map.get( c )+1) = map.get(c)+1 ) 时间复杂度O(n) 空间复杂度O(n)
class Solution { public int lengthOfLongestSubstring(String s) { int len = s.length(); if(len<=1)return len; Map<Character,Integer> map = new HashMap<>();//key:字符 value:字符对应的索引 int left = 0, right = 0,res = 0; while(right<len){ char c = s.charAt(right); if(!map.containsKey(c)){ map.put(c,right); } else{ left = Math.max(left,map.get(c)+1);//这样就能保证,如果是因为跟当前窗口之前(外)的字符重复,而不是跟当前窗口内的元素重复,那么此时left还是指向当前窗口的left,否则就指向发生重复的下一个位置 map.put(c,right);//别忘记这里,也需要把当前遍历的字符给压入窗口内 } right++; res = Math.max(res,(right-left)); } return res; } }