题目分析

题目链接:https://leetcode.com/problems...

题目补充:t可以包含重复的字符,如果t包含了n个c,那么找出的window也要包含n个c。

窗口是由2个游标确定的,我们应该合理地移动游标,枚举出所有包含给定字符的窗口,然后返回其中宽度最小的。

如何使我们的枚举能够不重复、不遗漏呢?要做到不重不漏地枚举,我们需要为每一种可能枚举出的元素定义一种“大小判断”,然后定义“如何从一个元素求出稍微大一些的下一个元素”(从当前的枚举迁移到下一个枚举)。最后,我们只要从最小到最大按序枚举,就能够保证不重不漏。

具体到这一题,我们要注意到以下特征:每个包含所有给定字符的窗口可以由它的慢游标唯一地指定。固定了慢游标以后,我们很容易就可以找出快游标应该在什么位置。比如,可以先看看下面这幅图:

加入将慢游标固定在C前面的位置(红色),那么快游标只能在H后面的那个位置,才能包含所有题目要求的字符。(当然,你可以说,将红色游标继续向右移动,得到的窗口也符合题意。但是这样做没有任何收益,反而将窗口的宽度变大了,因此我们不考虑这种窗口)
因此,慢游标的位置就可以作为一种比较窗口的标准。将慢游标从左往右移动的过程中,我们遇到的窗口越来越“大”。

假设我们已经有了一个符合题意的窗口(红色),要怎么得到下一个窗口(蓝色)呢?
如图所示,首先将慢游标右移,使得窗口变“大”,然后移动快游标,使窗口符合题意。

代码实现

class Solution
{public:string minWindow(string s, string t){// need_to_appear记录了当前window还缺少哪些字符、缺少多少次// unqualified_char_number记录了当前window中还缺少多少种字符// iterator_fast~iterator_slow 之间就是当前的windowvector<int> need_to_appear(256, 0);int unqualified_char_number = 0;// 已经找到的最小windowint min_window_begin = 0, min_window_end = 0;bool have_window = false;for (auto c : t){// 初始化每个字符还要出现的次数if (need_to_appear[c] == 0)unqualified_char_number++;need_to_appear[c]++;}for (int iterator_fast = 0, iterator_slow = 0; iterator_fast < s.size(); iterator_fast++){// 将当前字符的need_to_appear次数减一if (--need_to_appear[s[iterator_fast]] == 0){// 如果need_to_appear次数恰好变成0,说明当前window现在包含了足够数量的字符s[iterator_fast]unqualified_char_number--;if (unqualified_char_number == 0){// 如果unqualified_char_number恰好变成0,说明window现在包含了所有需要的字符// 向前移动iterator_slow,直到当前window恰好包含所有需要的字符// 这一步可以将不需要的字符排出windowwhile (++need_to_appear[s[iterator_slow]] <= 0){iterator_slow++;}// 比较当前window与已经找到的最小window,看看哪一个更小if (!have_window || iterator_fast - iterator_slow < min_window_end - min_window_begin){min_window_begin = iterator_slow;min_window_end = iterator_fast;have_window = true;}// iterator_slow向后移动,使window不再包含所有需要的字符iterator_slow++;unqualified_char_number++;}}}if (!have_window)return "";elsereturn s.substr(min_window_begin, min_window_end - min_window_begin + 1);}
};

算法的时间复杂度为O(n)。可能会人以为“代码中有嵌套循环,时间应该不是线性的”。然而,嵌套的while循环只是将慢游标接着上次的位置向右移,总共移动的次数不会超过s的长度。

另外一点值得注意的是,为了在O(1)时间内查询t中某个字符的信息(某个字符是不是在t中、还需要在窗口出现多少次),我们使用了一种哈希表的想法——need_to_appear,只不过这个哈希表直接使用字符本身作为键,因此不会出现冲突,并且保证能在O(1)时间内查询到。
这种直接用存储对象标识符作为键的方法只有在标识符种类不多的情况下使用。在这题,我们假设可能出现的字符只是0~255,加入所有Unicode中的字符都有可能出现,那么这种方式不再合理(需要创建多于65536个字符的数组)。

算法题解:找出包含给定字符的最小窗口(枚举的一般方法)相关推荐

  1. python判断几个数最大最小_python 找出list中最大或者最小几个数的索引方法

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  2. 【Python】最长括号匹配问题:给定字符串,仅包含左括号‘(’和右括号‘)’,它可能不是括号匹配的,设计算法,找出最长匹配的括号子串

    最长括号匹配 示例: 给定字符串,仅包含左括号'('和右括号')',它可能不是括号匹配的,设计算法,找出最长匹配的括号子串. 算法分析 只有在右括号和左括号发生匹配时,才有可能更新最终解. 计算s[0 ...

  3. 给定一个含n(n≥1)个整数的数组,请设计一个在时间上尽可能高效的算法,找出数组中未出现的最小正整数。

    笔者初涉<算法设计与分析>这门专业课,在做一些算法设计题的过程中遇到一些小感悟,特此记录和大家分享. 下面直接给出算法题目: 给定一个含n(n≥1)个整数的数组,请设计一个在时间上尽可能高 ...

  4. 请设计一个既节省时间又节省空间的算法来找出该链表中的倒数第m个元素

    给定一个单向链表(长度未知),请设计一个既节省时间又节省空间的算法来找出该链表中的倒数第m个元素. 实现这个算法,并为可能出现的特例情况安排好处理措施. 倒数第m个元素"是这样规定的:当m= ...

  5. 通过深度优先算法来找出有向图的树边,后向边,前向边,横跨边

    **通过深度优先算法来找出有向图的树边,后向边,前向边,横跨边(Java实现) ** package graph;import java.io.IOException; import java.uti ...

  6. 数据结构第5章例题 若矩阵Am×n中存在某个元素aij满足:aij是第i行中的最小值且是第j列中的最大值,则称该元素为矩阵A的一个鞍点。试编写一个算法,找出A中的所有鞍点。

    [例5.1] 若矩阵Am×n中存在某个元素aij满足:aij是第i行中的最小值且是第j列中的最大值,则称该元素为矩阵A的一个鞍点.试编写一个算法,找出A中的所有鞍点. 算法如下: void saddl ...

  7. C语言--在终端输入多行信息,找出包含“ould”的行,并打印改行

    问题: 在终端输入多行信息,找出包含"ould"的行,并打印改行. 如: Au,love could you and I with fate conspire To grasp t ...

  8. python找色_python实现从一组颜色中找出与给定颜色最接近颜色的方法

    本文实例讲述了python实现从一组颜色中找出与给定颜色最接近颜色的方法.分享给大家供大家参考.具体分析如下: 这段代码非常有用,可以找到指定颜色相似的颜色,比如有一组8个颜色,现在给定一个rgb格式 ...

  9. 典型的Top K算法_找出一个数组里面前K个最大数

    原文 典型的Top K算法_找出一个数组里面前K个最大数...或找出1亿个浮点数中最大的10000个...一个文本文件,找出前10个经常出现的词,但这次文件比较长,说是上亿行或十亿行,总之无法一次读入 ...

最新文章

  1. 剑指offer:正则表达式匹配
  2. [转]只让指定的机器连接SQLServer服务器
  3. NIOS生成Nios libaray
  4. da---tlc5615._CD-DA的完整形式是什么?
  5. eclipse web项目中css无法显示
  6. linux读写文件测试,Linux下各种主要文件系统的读写性能测试
  7. ssh 无法连接 z/OS 主机
  8. r语言plotmds_多元统计分析R语言建模| 11 多维标度法MDS
  9. 【时间同步】IEEE-1588总结
  10. Mixly(米思齐)图形化编程工具
  11. echarts全国省市县下钻
  12. 千古第一文人苏轼的众CP
  13. 分析docker启动MySQL挂载目录提示权限不足Permission denied原因
  14. 自适应滤波:递归最小二乘
  15. Windows 修改桌面Desktop的默认路径为D盘
  16. 【新示例】阿里系行业SaaS,企加云要做IOE的赋能者
  17. html在线预览ppt excel,JavaScript实现Word、Excel、PPT在线预览
  18. 计算机专业英语职高 试卷,2020年河南高职单招英语样卷及答案分享
  19. 【JY】YJK前处理参数详解及常见问题分析(一)
  20. 完全卸载 Minikube/Uninstall Minikube[ Linux 和 Mac]

热门文章

  1. 时间戳转为时间友好显示
  2. [转]几种软件测试工具
  3. Spring事务管理1-------环境搭建
  4. 知乎究竟走的是什么路线?克隆之路靠谱吗?
  5. 【mysql】MySQL存储IP地址
  6. list删除null
  7. 数据库递归查询(CET)
  8. 彻底封杀讯雷下载,做好网络管理
  9. Samba 3.4.0 发布
  10. Java的Interrupt与线程中断