目录
题目描述
给定一个字符串
s
,请你找出其中不含有重复字符的 最长子串
的长度。示例 1:
输入: s = "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是"abc"
,所以其长度为 3。示例 2:
输入: s = "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是"b"
,所以其长度为 1。示例 3:
输入: s = "pwwkew" 输出: 3 解释: 因为无重复字符的最长子串是"wke"
,所以其长度为 3。 请注意,你的答案必须是 子串 的长度,"pwke"
是一个子序列,不是子串。提示:
0 <= s.length <= 5 * 104
s
由英文字母、数字、符号和空格组成
方法一 滑动窗口
思路:
滑动窗口可以想象成一个左右边界会变动的队列,在队列中的就是不包含重复字符的子串,可以用left来记录队首的下标。从第一个开始,放入队列,更新长度。一个一个遍历放入放入...但是如果当前的的字符已经在队列中存在过了,就需要将left指针移到之前出现位置的下一个,并且更新该字符的位置,字符和字符的位置存在hashMap中。
判断滑动窗口中有没有当前字符,就是 在hashMap在找坐标,如果大于当前left就是在滑动窗口中。
代码:
class Solution {
public int lengthOfLongestSubstring(String s) {
if(s.length()==0) return 0;
HashMap<Character,Integer> map=new HashMap<Character,Integer>();
int max=0;
int left=0;
//abcababcdefghijk
for(int i=0;i<s.length();i++){
if(map.containsKey(s.charAt(i))){
// l:左界下标 r:右界下标
if(map.get(s.charAt(i)) <= i && map.get(s.charAt(i)) >= left ){
left = map.get(s.charAt(i)) + 1;//在窗口内, map.get(s.charAt(i)) + 1
}
else if(map.get(s.charAt(i)) < left){
left = left;//在窗口前,不变
}
}
map.put(s.charAt(i),i);
max=Math.max(max,i-left+1);
}
return max;
}
}