3.无重复字符的最长子串
2020-11-27 本文已影响0人
土豆泥加冰谢谢
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
示例 4:
输入: s = ""
输出: 0
提示:
0 <= s.length <= 5 * 104
s 由英文字母、数字、符号和空格组成
public static int lengthOfLongestSubstring(String s) {
//定义窗口性质:[left,right]前闭后闭范围内无重复字符
int ret=0;
//窗口左指针
int left=0;
//窗口右指针
int right=0;
Map<Character,Integer> windowData=new HashMap<>();
while(right<s.length()){
Character item=s.charAt(right);
if (windowData.containsKey(item)){
//遇到重复子串
//先记录下最大的连续长度
ret=Math.max(right-left,ret);
//接着对窗口数据进行维护,保证连续不重复,即移除窗口中重复字符和之前的字符,并且将left后移
int tempIndex=windowData.get(item);
for (int i=left;i<=tempIndex;i++){
windowData.remove(s.charAt(i));
}
left=tempIndex+1;
}else if(right==s.length()-1){
//如果走到末尾了,不要漏掉计算一次长度结果,因为可能在某次冲突后或者从未冲突,一直到结尾都是连续不重复的字符串
ret=Math.max(s.length()-left,ret);
}
//窗口继续右移判断下一位,并将当前数据纳入窗口
windowData.put(item,right);
right++;
}
return ret;
}
主要在于维护窗口性质,以及不要漏掉边界问题,例如整个字符串均连续不重复例如abcdefg,或者字符串结尾前一段字符为连续非重复例如:adbdeda.....abcdefg
//采用map来维护窗口数据,因为记录了字符下标,所以我们可以直接遍历移除到不重复字符为止。
在出现变种题目的情况下,例如要获取所有的无重复子串,只需要在该逻辑下增加一个数据结构来存储所有结果即可