滑动窗口的思路
增加窗口右边界,寻找一个可行解,在找到可行解的情况下增加窗口左边界,优化可行解,找到最优解
/* 滑动窗口算法框架 */
const slidingWindow = (s, t) => {
let need = new Map(), window = new Map();
for (let c of t){
need.set(c, (need.get(c) || 0) + 1);
}
let left = 0, right = 0, valid = 0;
// 记录最小覆盖子串的起始索引及⻓度
let start = 0, len = Number.MAX_SAFE_INTEGER;
while (right < s.length) {
// c 是将移入窗口的字符
const c = s[right];
// 右移窗口
right++;
// 进行窗口内数据的一系列更新
/*
if(need.has(c)) {
window.set(c, (window.get(c) || 0) + 1);
if (window.get(c) == need.get(c)) {
valid++;
}
}
*/
/*** debug 输出的位置 ***/
console.log("window", left, right);
// 判断左侧窗口是否要收缩
while (valid == need.size) {
// 在这里更新最小覆盖子串
/*
if (right - left < len) {
start = left;
len = right - left;
}
*/
// d 是将移出窗口的字符
const d = s[left];
// 左移窗口
left++;
// 进行窗口内数据的一系列更新
/*
if(need.has(d)) {
if (window.get(d) == need.get(d)) {
count--;
}
window.set(d, window.get(d) - 1);
}
*/
}
}
return len == Number.MAX_SAFE_INTEGER ? '' : s.substr(start, len);
}
一、最长无重复子串
function getMaxLenNorepeatStr(str){
let size = 1, //无重复字符串的长度
currentStr = '', //用来存储临时分割的最新一段字符串
norepeatStr = ''; // 结果字符串
for(let i = 0; i < str.length; i++) {
if(currentStr.includes(str[i])) {
currentStr = currentStr.slice(i + 1) + str[i];
} else {
currentStr = currentStr + str[i];
}
if(size < currentStr.length) {
size = currentStr.length;
norepeatStr = currentStr;
}
}
return norepeatStr;
}
getMaxLenNorepeatStr('abcadb') // 'bcad'