76.最小覆盖子串
具体的解题思路和代码我放到了下面供大家参考:
var minWindow = function(s, t) {
let left = 0, right = 0, vaild = 0;
let need = {};
let win_map = {};
// 装填需要的子串
for (let key of t) {
need[key] = (need[key] || 0) + 1;
}
console.log(need);
// 记录最小覆盖子串的起始索引及其长度 多的
let start = 0, len = Number.MAX_VALUE;
// 开始窗口右移
while(right < s.length) {
// c 是将移入窗口的字符
let c = s[right];
// 右移窗口
right++;
// 进行窗口内数据的一系列更新
if (need[c]) {
win_map[c] = (win_map[c] || 0) + 1;
if (win_map[c] === need[c]) {
vaild++;
}
}
// 判断左侧窗口是否要收缩,以及收缩条件是什么
while(vaild === Object.keys(need).length) {
// 这里更新最小覆盖子串
console.log('right', right, 'left', left);
if (right - left < len) {
start = left;
len = right - left;
console.log('len', len);
}
// d 是将移出窗口的字符
let d = s[left];
// 左移窗口
left++;
// 进行窗口内数据的一系列更新
if(need[d]) {
if (win_map[d] === need[d]) {
vaild--;
}
win_map[d]--;
}
}
}
// 返回最小的覆盖子串
return len === Number.MAX_VALUE ? "" : s.substr(start, len);
};
这里还需要注意 for of
和 for in
使用上的不同
let s = 'abc'
let s_obj = {};
for(let i of s) {
s_obj[i] = (s_obj[i] || 0) + 1
}
// {a: 1, b: 1, c: 1}
let l_obj = {};
for(let i in s) {
l_obj[i] = (s_obj[i] || 0) + 1
}
// {0: 1, 1: 1, 2: 1}
567. 字符串的排列
解题思路:
var checkInclusion = function(s1, s2) {
let left = 0, right = 0, valid = 0;
let need = {}, win_obj = {};
// 装填需要的子串
for (let k of s1) {
need[k] = (need[k] || 0) + 1;
}
console.log('need', need);
// let start = 0, len = Number.MAX_VALUE; 不要了
// right 开始滑动窗口 ---> 怎么滑不会遍历啊
while(right < s2.length) { // 最后困在这里了
let c = s2[right];
right++;
if (need[c]) { // 合法写入
win_obj[c] = (win_obj[c] || 0) + 1;
if (win_obj[c] === need[c]) {
valid++;
}
}
// left 出场了左边 需要减小滑动窗口
while(right - left >= s1.length) { // 最后困在这里了
if (valid === Object.keys(need).length) {
return true;
}
// 如果暂时没有找到合法的怎么办呢? 左移减小区间
let d = s2[left];
left++; // left 没更新
if (need[d]) { // 这边要对称的合法的输出
// valid--; 少了
if (win_obj[d] === need[d]) {
valid--;
}
win_obj[d]--;
}
}
}
return false;
};
438.找到字符串中所有字母的异或词
解题思路:
var findAnagrams = function(s, p) {
let need = {}, window ={};
let left = 0, right = 0;
// 装填需要的子串
for (let k of p) {
need[k] = (need[k] || 0) + 1;
}
console.log(need);
let valid = 0, res = [];
// 右移
while(right < s.length) {
let c = s[right];
right++;
// window[c] = (window[c] || 0) + 1;
if (need[c]) { //
window[c] = (window[c] || 0) + 1;
if (window[c] === need[c]) {
valid++;
}
}
while(right - left >= p.length) { //right - left > p.length [0,5,6]
// 满足条件的情况下
if (valid === Object.keys(need).length) {
console.log('left', left);
res.push(left);
}
// 否则
let d = s[left];
left++;
// 窗口更新 ---> 不会
if (need[d]) {
if (window[d] === need[d]) {
valid--
}
window[d]--;
}
}
}
return res;
};
3. 无重复最长子串
解题思路:
var lengthOfLongestSubstring = function(s) {
let left = 0, right = 0, window = new Set();
let res = 0; //记录结果
while(left < s.length) {
while(right < s.length && !window.has(s[right])) {
window.add(s[right])
right++;
}
// 不满足上述条件--左侧窗口要收缩
res = Math.max(res, right - left);
window.delete(s[left]);
left++;
}
return res;
};
参考学习资料