(1)对应lc题型:713.乘积小于K的子数组、209.长度最小的子数组、 1004.最大连续1的个数
int i = 0, j = 0;
int res, sum; //sum, res根据条件(个数,长度等)初始化
while(j < nums.size()) { //窗口变化
xxx; //统计变量 如sum += nums[i]; sum *= nums[i]; if(nums[i] == ?) ~
while(xxx) { //窗口缩小条件
xxx; //缩小窗口前更新结果,如res = min(res, j - i + 1);
xxx; //如 sum -= nums[i]; sum /= nums[i];
i++; //缩小窗口
}
xxxxx; //也可能在这更新结果,如res = max(res, j - i + 1); res += j - i + 1;
j++; //增大窗口
}
(2)对应lc(或牛客Top)题型:MD92 最长无重复子数组、3.无重复字符的最长子串、 76.最小覆盖子串 567.字符串的排列、438.找到字符串中所有字母异位词
//一个字符串的情况(string s):经典题:最长无重复子串(子数组) unordered_map注意:map; //哈希表根据题意构造,value值通常是个数表示某字符(数)出现多少次、是否出现(重不重复) int l = 0, r = 0; //维护一个左闭右开的[l,r)窗口 int res; //res记录结果 while(r < s.size()) { char c = s[r]; r++; map[c]++; while(xxx) { //缩小窗口条件,如map[c] > 1 char d = s[l]; l++; map[d]--; } xxx; //结果res更新 } //两个字符串的情况(string s, string t),窗口更新逻辑较为复杂 unordered_map window, need; for(char c : t) need[c]++; int l = 0, r = 0; int res, valid = 0; //其中res记录结果(也可能是数组), valid记录合格字符数量 while(r < s.size()) { char c = s[r]; r++; xxx; //窗口数据更新 while(xxx) { //缩小窗口条件,如valid == need.size() xxx; //可能在这里更新结果res(或者返回bool值) char d = s[l]; l++; xxx; //窗口数据更新 } }
1.结果更新位置不固定,可能在窗口真正缩小前,也可能在其之后(特指内层while后)。
2.内层while循环上下具有一定的相似性(对称性)。
3.哈希表框架的前提是维护了一个左闭右开的区间:窗口。相对哈希表,计数变量框架的窗口增大逻辑往往放在内层while循环之后,数据更新通常在二者之间。
4.此框架仅针对子串(子数组)问题,使用前也具有一定的条件限制。比如统计数的和或者乘积时数为正数(或非负数),若存在负数那么可能就是其它形如动态规划或贪心求解的最大子数组和问题了。
参考:labuladong
博客首文,不好的地方欢迎提出批评。



