双指针
滑动窗口
滑动窗口和双指针法的不同和相同
不同:双指针法 俩个指针都是 指向不同的元素 可能是目标数组的前后端
然后进行遍历
而滑动窗口也是指向不同的元素但是滑动窗口(即俩个指针的遍历方向 相同
保证一次遍历的情况下,不断更新滑动窗口(自定义的结果集)保证最后输出的结果是最优解
去重
使用set,arraylist 数组
当需要按顺序查找,以及对于数组下标有要求的时候 就使用arraylist 数组
如果对于数组本身没有要求 只需要简单进行搜索等 使用set 数组进行查询
求重
使用hash表记录出现次数
如果需要替换 即使用滑动窗口 减去 本身所包含的次数
用哈希表记录字符串s、t中出现过的字符以及对应出现次数。
滑动窗口扫描字符串t,移动右边界直到满足覆盖t中所有字符的条件,开始移动左边界,更新最小的覆盖字串。循环体格式如下
while (r < sLen) {
//++r不可以放在循环体末尾,这样最后一个字符无法被检查。
++r;
//
while (满足窗口条件){
//更新
//移动左边界
}
return ;
滑动窗口 例题
给两个字符串,S 和 T,在 S 中找出包含 T 中所有字母的最短字符串,不考虑顺序。
S = "ADOBECODEBANC", T = "ABC"
A D O B E C O D E B A N C //l 和 r 初始化为 0
^
l
r
A D O B E C O D E B A N C //向后移动 r,扩大窗口
^ ^
l r
A D O B E C O D E B A N C //向后移动 r,扩大窗口
^ ^
l r
A D O B E C O D E B A N C //向后移动 r,扩大窗口
^ ^
l r
A D O B E C O D E B A N C //向后移动 r,扩大窗口
^ ^
l r
//此时窗口中包含了所有字母(ABC),停止移动 r,记录此时的 l 和 r,然后开始移动 l
A D O B E C O D E B A N C
^ ^
l r
//向后移动 l,减小窗口,此时窗口中没有包含所有字母(ABC),重新开始移动 r,扩大窗口
A D O B E C O D E B A N C
^ ^
l r
//移动 r 直到窗口包含了所有字母(ABC),
//和之前的长度进行比较,如果窗口更小,则更新 l 和 r
//然后开始移动 l,开始缩小窗口
A D O B E C O D E B A N C
^ ^
l r
//此时窗口内依旧包含所有字母
//和之前的长度进行比较,如果窗口更小,则更新 l 和 r
//继续移动 l,继续缩小窗口
A D O B E C O D E B A N C
^ ^
l r
//此时窗口内依旧包含所有字母
//和之前的长度进行比较,如果窗口更小,则更新 l 和 r
//继续移动 l,继续缩小窗口
A D O B E C O D E B A N C
^ ^
l r
//继续减小 l,直到窗口中不再包含所有字母,然后开始移动 r,不停的重复上边的过程,直到全部遍历完
题解示意图
重点分为俩步
1.先将窗口右移找到的包含所有字符串的滑动窗口 记录滑动窗口的长度
2.在移动窗口的左指针:如果移动后,没有包含所有字符串 继续移动右指针 如果依旧包含的话 记录滑动窗口的长度 继续移动左指针
重点:
判断窗口内是否包含所有的字符
1.俩个hashmap 进行匹配
2.还可以用一个计数变量 count,把 count 初始化为 t 的长度,然后每次找到一个满足条件的字母,count 就减 1,如果 count 等于了 0,就代表包含了所有字母
或者 使用match 加加看是否是equal
其次因为字符串里面只有字母甚至可以不用hashmap 知识单传用数组来计算 缩短空间使用率
总结
在解算法题的时候要关注的一个点 是他只是需要得到最为关键的答案 而不是解题的全过程