const str = 'Canyoufindthelongeststringinthissentence';
方法一:滑动窗口法,基本思路就是定义一个窗口在字符串上向右滑动,
窗口右边滑动时,判断进入窗口的字符是否有重复。
若有重复,则窗口左边也向右滑动,直到没有重复字符。
在滑动过程中,记录窗口中没有重复字符的最大长度。
function findLongestStr(str) {
const strLen = str.length;
if(strLen<=1){
return strLen;
}else{
let strSet = new Set();
let left = 0, right = 0, maxLen = 0;
for(let i=0;i<strLen;i++){
const letter = str[i];
right++;
if(strSet.has(letter)){
while(left<=right && strSet.has(letter)){
strSet.delete(str[left]);
left++;
}
}
strSet.add(letter);
maxLen = Math.max(maxLen,right-left);
}
return maxLen;
}
};
方法二: 定义的变量比较多,属于滑动窗口法的变形。
外层的循环是一样的,区别是使用Map替代Set,不仅存储了出现过的字符,
还存储了字符最近一次出现的索引位置,
这样就可以省去内层while循环。
function findLongestStr(str) {
const strLen = str.length;
if(strLen<=1){
return strLen;
}
let strMap = new Map();
let maxLen = 0, maxLexIdx = 0, curLen = 0, curLenIdx = 0;
for(let i=0; i<strLen; i++){
const letter = str[i];
const preIndex = strMap.get(letter);
if(preIndex!=undefined && preIndex>=curLenIdx){
if(curLen>maxLen){
maxLen = curLen;
maxLenIdx = curLenIdx;
}
curLenIdx = preIndex+1;
curLen = i - preIndex;
}else{
curLen++;
}
strMap.set(letter,i);
maxLen = Math.max(maxLen,curLen)
}
return maxLen;
};