找出从每一个字符开始的,不包含重复字符的最长子串。
思路:
其实可以这样理解,两个指针维护的就是一个窗口,我们需要做的就是保证在这个窗口里面,没有重复字符。在while循环中删除了set[j]还是为了在当前窗口中没有重复的字符串。当然此时右边的指针i是不用移动的,因为前面都已经判断出了[j,i]区域的字符串是不重复的。如果一直遇见ccccccc这种重复的,滑动窗口大小始终为1,ij指针重合。
class Solution { public int lengthOfLongestSubstring(String s) { HashSet<Character> set=new HashSet<>(); int maxLength=0; int j=0; if(s.length()==0){ return 0; } for(int i=0;i<s.length();i++){ if(!set.contains(s.charAt(i))){ set.add(s.charAt(i)); //加入新的元素,则窗口往后面移动一格 maxLength=Math.max(maxLength,set.size()); }else{ while(set.contains(s.charAt(i))){ //移动左边的指针 set.remove(s.charAt(j)); j++; } //删除后要加上新的set中没有的字符 set.add(s.charAt(i)); } } return maxLength; } }
滑动窗口还有更优雅的做法
var lengthOfLongestSubstring = function(s) { let set=new Set(); let i=0,j=0,maxLength=0; if(s.length===0){ return 0; } for(i;i<s.length;i++){ if(!set.has(s[i])){ set.add(s[i]); maxLength=Math.max(maxLength,set.size) }else{ while(set.has(s[i])){ set.delete(s[j]); j++; } set.add(s[i]); } } return maxLength; };
set 的操作 add delete