建议先读文章,本文解决一类最难掌握的双指针技巧:滑动窗口技巧。

难度在于各种细节问题,比如:如何向窗口中添加新元素,如何缩小窗口,在窗口滑动的哪个阶段更新结果。

技术:

  1. 用到的数据结构——哈希表(字典)
  2. 直接使用对象来代替map,1. 获取键的长度 , 2. 不需要get,set方法。
  3. 字符串遍历
  4. window[c] = (window[c] || 0) + 1; 如果键不存在时,赋初始值。不需要先判断

代码模板:

/* 滑动窗口算法框架 */
void slidingWindow(string s, string t) {unordered_map<char, int> need, window;for (char c : t) need[c]++;int left = 0, right = 0;int valid = 0; while (right < s.size()) {// c 是将移入窗口的字符char c = s[right];// 右移窗口right++;// 进行窗口内数据的一系列更新.../*** debug 输出的位置 ***///printf("window: [%d, %d)\n", left, right);/********************/// 判断左侧窗口是否要收缩while (window needs shrink) {// 在这里更新最小覆盖子串...// d 是将移出窗口的字符char d = s[left];// 左移窗口left++;// 进行窗口内数据的一系列更新...}}return 所需字符串
}

76. 最小覆盖子串 (困难)

这个思路其实也不难,第 2 步相当于在寻找一个「可行解」,然后第 3 步在优化这个「可行解」,最终找到最优解,也就是最短的覆盖子串。左右指针轮流前进,窗口大小增增减减,窗口不断向右滑动,这就是「滑动窗口」这个名字的来历。

needs 和 window 相当于计数器,分别记录 T 中字符出现次数和「窗口」中的相应字符的出现次数。

进行窗口内数据的一系列更新:window的字符数量增加,统计覆盖的字符数

/*** @param {string} s* @param {string} t* @return {string}*/
var minWindow = function(s, t) {let need = new Map(), window = new Map();for (let c of t){need.set(c, (need.get(c) || 0) + 1); //代码功底}let left = right = count = start = 0;let minlen = Number.MAX_SAFE_INTEGER;while (right < s.length) {let c = s[right];right++;// 当前字符在t字符串中,才更新窗口的统计if(need.has(c)) {window.set(c, (window.get(c) || 0) + 1);// 等于, 才说明某字符完成覆盖if (window.get(c) == need.get(c)) {count++;}}// 判断左侧窗口是否要收缩while (count == need.size) {let temp = right - left;if (temp < minlen) {start = left;minlen = temp;}let c = s[left];left++;if(need.has(c)) {//再减就不够数覆盖某字符if (window.get(c) == need.get(c)) {count--;}window.set(c, window.get(c) - 1);}}}return minlen == Number.MAX_SAFE_INTEGER ? "" : s.substr(start, minlen);
};

可参考

567. 字符串的排列 (中等)

注意:输入的 s1 是可以包含重复字符的。排列之一:包含s1中所有字符,不能多余且不包含其他字符。即:窗口大小等于s1的长度,窗口大小固定也能运用上面的框架,先移入后移出。

技巧:要覆盖s1字符时,因为窗口限制了大小,不可能有多余的字符,

区别:如果所有字符都覆盖了,则结束。而上一题则是开始缩圈。

/*** @param {string} s1* @param {string} s2* @return {boolean}*/
var checkInclusion = function(s1, s2) {let need = {}, window = {};for (let c of s1) {need[c] = (need[c] || 0) + 1;}let left = right = count = 0;let maxlen = s1.length, target = Object.keys(need).length;while (right < s2.length) {let c = s2[right]right++// 处理移入的字符if(need[c]) {window[c] = (window[c] || 0) + 1;if(window[c] == need[c]) count++;}// 判断左侧窗口是否要收缩while (right-left == maxlen) {// 判断结果if (count == target) return true;let c = s2[left]left++// 处理移入的字符if(need[c]) {                if(window[c] == need[c]) count--;window[c]--;}}}return false;
};

个人觉得:有了这个框架,优点:更容易记住,不需要管别人怎么写了。缺点:一开始花时间。

JS:滑动窗口算法 (上集)相关推荐

  1. 列表左右箭头滑动_我写了一套框架,把滑动窗口算法变成了默写题

    读完本文,你可以去力扣拿下如下题目: 76.最小覆盖子串 567.字符串的排列 438.找到字符串中所有字母异位词 3.无重复字符的最长子串 ----------- 鉴于前文 二分搜索框架详解 的那首 ...

  2. 滑动窗口算法_有点难度,几道和「滑动窗口」有关的算法面试题

    前言科普:什么是滑动窗口算法 滑动问题包含一个滑动窗口,它是一个运行在一个大数组上的子列表,该数组是一个底层元素集合. 假设有数组 [a b c d e f g h ],一个大小为 3 的 **滑动窗 ...

  3. 从零开始学习VIO笔记 --- 第四讲:滑动窗口(基于滑动窗口算法的 VIO 系统:可观性和一致性)

    从零开始学习VIO笔记 --- 第四讲:滑动窗口(基于滑动窗口算法的 VIO 系统:可观性和一致性) 一. 从高斯分布到信息矩阵 1.1 高斯分布 1.2 高斯分布和协方差矩阵 1.3 信息矩阵 二. ...

  4. 滑动窗口算法通用思想

    文章目录 一.最小覆盖子串 二.找到字符串中所有字母异位词 三.无重复字符的最长子串 最后总结 本文详解「滑动窗口」这种高级双指针技巧的算法框架,带你秒杀几道难度较大的子字符串匹配问题: 最小覆盖子串 ...

  5. c语言怎么实现滑动窗口算法,【C语言】滑动窗口算法

    1.滑动窗口的思想: 它是一个运行在一个大数组上的子列表,该数组是一个底层元素集合.假设有数组 [a b c d e f g h ],一个大小为 3 的 滑动窗口 在其上滑动,则有: [a b c] ...

  6. sentinel 时间窗口_Sentinel滑动窗口算法

    在前面搞清楚了Sentinel的使用后,大致理了一下Sentinel的责任链,搞清楚了这个,基本就已经梳理清楚sentinel-core模块的大部分内容,顺着这条链路可以继续梳理很多东西. 知其然.知 ...

  7. 滑动窗口算法用法及实题详解

    在力扣常用解题法中,我们常常会看到这些: 滑动窗口 双指针 快慢指针/ 链表题目 原地链表翻转 区间合并 无序限定范围的数组元素查找O(N) BFS 树的DFS DFS/递归/回溯法 双堆模式 2分变 ...

  8. 滑动窗口算法基本原理与实践

    原文作者:huansky 原文地址:滑动窗口算法基本原理与实践 目录 滑动窗口算法(Sliding Window Algorithm) 基本示例 滑动窗口法的大体框架 算法实例 1208. 尽可能使字 ...

  9. “滑动窗口”算法详解

    一.概念 滑动窗口算法是在给定特定窗口大小的数组或字符串上执行要求的操作.该技术可以将一部分问题中的嵌套循环转变为一个单循环,因此它可以减少时间复杂度. 简而言之,滑动窗口算法在一个特定大小的字符串或 ...

最新文章

  1. struts2框架之国际化(参考第二天学习笔记)
  2. HDU 6304 Chiaki Sequence Revisited
  3. 5种较为简单的缺失值处理方法
  4. 基础命令之cd,mkdir,cp,ls
  5. Hadoop系列(三)MapReduce Job的几种提交运行模式
  6. string类的erase函数属于stl吗_C++ STL快速入门
  7. 基于php的医院管理,基于PHP的医院管理信息系统的设计与实现
  8. 今天在当当上看到一本书,ASP.NET程序员参考手册
  9. 三菱plc控制步进电机实例_「PLC案例」三菱FX3U与威纶通HMI的步进定位控制,附程序图~...
  10. 用C为密集运算函数加速
  11. java vo的使用_使用VO传递参数的设计 | 学步园
  12. Day3 函数 参数 变量 递归——python学习之路
  13. Crust Network 与京湘豫等地区块链名企、投资人考察广西区块链科创园
  14. Apollo安装记录
  15. 2-04-调用函数-0518
  16. echarts柱状图 双柱状图基本用法
  17. 自己动手、丰衣足食!箭头 → ← → ← ---1
  18. C语言链接mysql数据库实现简易的学生信息增删改查
  19. 使用QT获取当前星期的中英文显示
  20. 【Matlab学习笔记】控制运算精度digits和vpa函数

热门文章

  1. 流水线乘法器的原理及verilog代码
  2. java cookie 无法删除不了_java中无法删除cookie之解决
  3. 食品科学系-软件开发
  4. 基于nodejs爬虫
  5. 微信qq拦截检测易语言代码
  6. 苹果5壁纸_抖音超火的桌面时钟壁纸,不仅酷炫还能报时
  7. 字节面试官:一条sql执行慢的原因?如何优化?
  8. VisualStudio2017发布网站时提示构建错误
  9. 关于App的一些迷思以及一些动画效果开源库的推荐
  10. java计算机类在线学习管理系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署