已知:
给定一个字符串 s,求 字符串 s 不含有重复字符的 最长子串 的长度。
如输入:"abcabcbb" 应输出:"3" ,最长子串为abc
分析:
方法一:
从字符的起始位置开始,找出以每一个字符开始的,不含重复字符的子串,计算出最大长度。
我们使用两个指针表示字符串中的某个子串(或窗口)的左右边界,其中左指针代表着「枚举子串的起始位置」。在左指针向右移动的时候,我们从哈希集合中移除一个字符,在右指针向右移动的时候,我们往哈希集合中添加一个字符。
代码如下
var lengthOfLongestSubstring = function(s) {
// 创建哈希集合用于记录字符是否重复
const agg = new Set();
// 创建右指针,默认为-1,此时还未开始移动,处于初始位置,即指向最左边
// 记录最长子串长度maxLength,默认值为0
let right = -1,maxLength = 0;
for(let i = 0; i< s.length;i++) {
if(i!=0) {
// 左指针向右移动一格,移除一个元素
// 使用charAt(index)返回指定索引处的值。
agg.delete(s.charAt(i-1));
}
// 使用while,进行循环判断字符是否重复
while(right + 1 < s.length && !agg.has(s.charAt(right+1))) {
// 右指针向右移动一格,添加一个元素
agg.add(s.charAt(right+1));
++right;
}
// 求出子串的最大长度
maxLength = Math.max(maxLength,right-i+1);
}
return maxLength;
};
方法二:
在字符串自身进行滑动
代码如下:
var lengthOfLongestSubstring = function(s) {
// 窗口起始位置,默认为0
let minIndex = 0;
// 最长子串长度,默认为0
let maxLength = 0;
for(let i = 0; i < s.length; i++){
// 判断Index是否重复
if(s.indexOf(s[i], minIndex) < i) {
//有重复字符,窗口起始位置为该字母的出现的第一个位置
minIndex = s.indexOf(s[i], minIndex) + 1;
}
else {
//求出最长子串长度
maxLength = Math.max(maxLength, i - minIndex + 1);
}
}
return maxLength;
};