给定一个字符串 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
由英文字母、数字、符号和空格组成
思路:双标志位滑动窗口
1、设置左右边界来进行窗口滑动,起始位置都在0;设置变量记录最长长度
2、左边界在当前位置时,右边界所指字符不重复就继续右移并将该字符放入集合中,并更新最长长度;若产生重复,则停止右移跳出循环
3、左边界将该位置字符从集合中删除并右移
var lengthOfLongestSubstring = function(s) {
var n = s.length; //数组长度
var r = 0,ans = 0; //右标志位,最长长度记录
var set = new Set(); //声明集合,来判断是否重复
for(let i = 0;i < n;i++){ //左标志位i
//每个i位置时,右标志位移动找到最长不重复字符,注意r不是每次从0开始
for(;r < n;r++){
if(!set.has(s.charAt(r))){ //字符不重复则放入集合并更新最大长度
set.add(s.charAt(r));
ans = Math.max(ans,r - i + 1)
}else{ //字符重复则跳出循环
break;
}
}
set.delete(s.charAt(i)) //左标志位右移前先把该字符从集合移除
}
return ans;
};
复杂度分析
-
时间复杂度:O(N),其中 N 是字符串的长度。左指针和右指针分别会遍历整个字符串一次。
-
空间复杂度:O(∣Σ∣),其中 Σ 表示字符集(即字符串中可以出现的字符),∣Σ∣ 表示字符集的大小。