3. 无重复字符的最长子串
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
{ a: 1 } l=0 r=1 res=1
{ a: 1, b: 1 } l=0 r=2 res=2
{ a: 1, b: 1, c: 1 } l=0 r=3 res=3
{ a: 1, b: 1, c: 1 } l=1 r=4 res=3
{ a: 1, b: 1, c: 1 } l=2 r=5 res=3 `
{ a: 1, b: 1, c: 1 } l=3 r=6 res=3
{ a: 0, b: 1, c: 1 } l=5 r=7 res=3
{ a: 0, b: 1, c: 0 } l=7 r=8 res=3
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
let l = 0;
let r = 0;
let res = 0;
let map = {}; // 维护一个无重复字符的窗口
while(r < s.length) {
let temp = s[r];
r++; // 窗口内容无重复之前,始终扩张窗口
map[temp] = (map[temp] || 0) + 1; // 增加窗口内容
while(map[temp] > 1) { // 窗口内容有重复,则缩小窗口
map[s[l]]--; // 缩小窗口内容
l++; // 缩小窗口
}
res = Math.max(res, r-l); // 更新最长子串长度
console.info(map);
console.info('l='+l);
console.info('r='+r);
console.info('res='+res);
}
return res;
};
/**
* @param {string} s
* @return {number}
*/
var lengthOfLongestSubstring = function(s) {
let l = 0; let r = 0;
let res = 0; let map = new Map();
while(r < s.length) {
while(map.has(s[r])) {
map.delete(s[l]);
l++;
}
map.set(s[r], 1);
r++;
res = Math.max(res, r - l);
}
return res;
};
209. 长度最小的子数组
给定一个含有 n 个正整数的数组和一个正整数 target 。
找出该数组中满足其和 ≥ target 的长度最小的 连续子数组 [numsl, numsl+1, …, numsr-1, numsr] ,并返回其长度。如果不存在符合条件的子数组,返回 0 。
输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。
2 l=0 r=1 res=Infinity
5 l=0 r=2 res=Infinity
6 l=0 r=3 res=Infinity
6 l=1 r=4 res=4
6 l=3 r=5 res=3
3 l=5 r=6 res=2
/**
* @param {number} target
* @param {number[]} nums
* @return {number}
*/
var minSubArrayLen = function(target, nums) {
let l = 0; let r = 0;
let res = Infinity;
let sum = 0; // 维护一个子数组的和大于等于target
while(r < nums.length) {
let cur = nums[r];
r++; // 子数组的和大于等于target之前,始终扩张窗口
sum += cur;
while(sum >= target) { // 子数组的和大于等于target,则缩小窗口
res = Math.min(res, r - l); // 更新长度最小的子数组
sum -= nums[l];
l++; // 缩小窗口
}
console.info(sum);
console.info('l='+l);
console.info('r='+r);
console.info('res='+res);
}
return res === Infinity ? 0 : res;
};
904. 水果成篮
输入: [1,2,3,2,2]
输出: 4
解释: 我们可以收集 [2,3,2,2] 如果我们从第一棵树开始,我们将只能收集到 [1, 2]。
{ '1': 1 } l=0 r=1 res=1
{ '1': 1, '2': 1 } l=0 r=2 res=2
{ '1': 0, '2': 1, '3': 1 } l=1 r=3 res=2
{ '1': 0, '2': 2, '3': 1 } l=1 r=4 res=3
{ '1': 0, '2': 3, '3': 1 } l=1 r=5 res=4
/**
* @param {number[]} fruits
* @return {number}
*/
var totalFruit = function(tree) {
let l = 0; let r = 0;
let map = {}; // 维护一个连续水果种类为2的窗口
let count = 0; // 能携带水果的类型,最多2种
let res = 0; // 能收集的水果树的最大总量
while(r < tree.length) {
let cur = tree[r];
r++; // 收集的连续水果种类大于2之前,始终扩张窗口
if(map[cur]) {
map[cur]++;
} else {
map[cur] = 1;
count++; // 增加目前收集的水果类型
}
while(count > 2) { // 收集的连续水果种类大于2,缩小窗口
map[tree[l]]--;
if(!map[tree[l]]) count--; // 减少目前收集的水果类型
l++;
}
res = Math.max(res, r - l);
console.info(map);
console.info('l='+l);
console.info('r='+r);
console.info('res='+res);
}
return res;
};
1052. 爱生气的书店老板
输入:customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], X = 3
输出:16
解释:
书店老板在最后 3 分钟保持冷静。
感到满意的最大客户数量 = 1 + 1 + 1 + 1 + 7 + 5 = 16.
count=0 l=0 r=1 r-l=1 max=0
count=0 l=0 r=2 r-l=2 max=0
count=0 l=0 r=3 r-l=3 max=0
count=2 l=1 r=4 r-l=3 max=2
count=2 l=2 r=5 r-l=3 max=2
count=3 l=3 r=6 r-l=3 max=3
count=1 l=4 r=7 r-l=3 max=3
count=6 l=5 r=8 r-l=3 max=6
/**
* @param {number[]} customers
* @param {number[]} grumpy
* @param {number} minutes
* @return {number}
*/
var maxSatisfied = function(customers, grumpy, minutes) {
let len = grumpy.length;
let l = 0; let r = 0;
let count = 0; // 老板不生气时,顾客满意最大数(每次循环时)
let max = 0; // 老板不生气时,顾客满意最大数
while (r < len) {
if(grumpy[r] === 1) count += customers[r];
r++; // 在老板不让自己生气的时间内,始终扩张窗口
while(r - l > minutes) { // 超出老板不生气的时间后,缩小窗口
if(grumpy[l] === 1) count -= customers[l];
l++;
}
max = Math.max(max, count); // 更新老板不生气时,顾客满意最大数
console.info('count='+count);
console.info('l='+l);
console.info('r='+r);
console.info('r-l='+(r-l));
console.info('max='+max);
}
let res = 0; // 不生气时的客户数量
for (let i = 0; i < len; i++) {
res += (grumpy[i] === 0 ? customers[i] : 0);
}
return res + max;
};
187. 重复的DNA序列
所有 DNA 都由一系列缩写为 ‘A’,‘C’,‘G’ 和 ‘T’ 的核苷酸组成,例如:“ACGAATTCCG”。在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮助。
编写一个函数来找出所有目标子串,目标子串的长度为 10,且在 DNA 字符串 s 中出现次数超过一次。
输入:s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT"
输出:["AAAAACCCCC","CCCCCAAAAA"]
{ AAAAACCCCC: 1 } l=1 r=10
{ AAAAACCCCC: 1, AAAACCCCCA: 1 } l=2 r=11
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1 } l=3 r=12
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1 } l=4 r=13
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ACCCCCAAAA: 1 } l=5 r=14
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ACCCCCAAAA: 1, CCCCCAAAAA: 1 } l=6 r=15
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ACCCCCAAAA: 1, CCCCCAAAAA: 1, CCCCAAAAAC: 1 } l=7 r=16
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ACCCCCAAAA: 1, CCCCCAAAAA: 1, CCCCAAAAAC: 1, CCCAAAAACC: 1 } l=8 r=17
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ACCCCCAAAA: 1, CCCCCAAAAA: 1, CCCCAAAAAC: 1, CCCAAAAACC: 1, CCAAAAACCC: 1 } l=9 r=18
{ AAAAACCCCC: 1, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ACCCCCAAAA: 1, CCCCCAAAAA: 1, CCCCAAAAAC: 1, CCCAAAAACC: 1, CCAAAAACCC: 1, CAAAAACCCC: 1 } l=10 r=19
{ AAAAACCCCC: 2, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ACCCCCAAAA: 1, CCCCCAAAAA: 1, CCCCAAAAAC: 1, CCCAAAAACC: 1, CCAAAAACCC: 1, CAAAAACCCC: 1 } l=11 r=20
{ AAAAACCCCC: 2, AAAACCCCCA: 1, AAACCCCCAA: 1, AACCCCCAAA: 1, ... 235 more lines
/**
* @param {string} s
* @return {string[]}
*/
var findRepeatedDnaSequences = function(s) {
let map = {};
let res = [];
let l = 0; let r = 9;
while(r < s.length) {
let temp = s.slice(l, r + 1); // 始终维护10个元素的窗口
map[temp] = (map[temp] || 0) + 1;
l++;
r++;
console.info(map);
console.info('l='+l);
console.info('r='+r);
}
Object.entries(map).map(([k, v] = [...item]) => {if(v > 1) res.push(k)});
return res;
};
/**
* @param {string} s
* @return {string[]}
*/
var findRepeatedDnaSequences = function(s) {
let map = new Map();
let res = [];
let l = 0; let r = 10;
while(r <= s.length) {
let temp = s.slice(l, r);
map.set(temp, map.has(temp) ? map.get(temp) + 1 : 1);
l++;
r++;
}
for(let [k, v] of map) {
if(v > 1) res.push(k);
}
return res;
};