给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的子串。

注意事项

如果在source中没有这样的子串,返回"",如果有多个这样的子串,返回起始位置最小的子串。

说明

在答案的子串中的字母在目标字符串中是否需要具有相同的顺序?

——不需要。

样例

给出source = "ADOBECODEBANC",target = "ABC" 满足要求的解  "BANC"

标签

 
 

解题:这个题目关于最小子串覆盖,跟字符串匹配还是有区别的,所以不可以用KMP来求解。

思路:

采用哈希的思想,记录字母出现次数。

【方法:可以定义一个整形数组,利用映射 map<char,int> m; 定义一个关联容器也可。】

首先预处理target,用256大小的整数数组t存储里面每个char出现的个数;
然后给定两个指标beg和end,一个移动start,也用一个256长的整数数组s记录从beg到end的这段字符串里面每个char出现的个数。如果
s大于等于t,也就是说s里的每一位大于等于t里相应位置的值,找到当前start位置,为符合要求子串的起点,记录当前beg和end的长度,如果比已经记录最小长度小,那么我们就选这个位最小窗口。记录beg和end。然后让start往前走一位。寻找下一个子串。

代码如下:

  1. class Solution {
  2. public:
  3. /**
  4. * @param source: A string
  5. * @param target: A string
  6. * @return: A string denote the minimum window
  7. * Return "" if there is no such a string
  8. */
  9. string minWindow(string &source, string &target) {
  10. // write your code here
  11.  
  12. if (source.empty()||target.empty()){
  13. return "";
  14. }
  15.  
  16. int slength=source.length(); //size()和length()都是返回字符串的长度,本质上没有区别;
  17. int tlength=target.length();
  18.  
  19. int s[],t[];
  20. memset(s,,sizeof(s));
  21. memset(t,,sizeof(t));
  22.  
  23. for(int i=;i<target.length();i++){ //统计目标串中每个字符出现的次数;
  24. t[target[i]]++;
  25. }
  26.  
  27. int beg = -, end = slength, found = , minLen = slength; //将最小长度先赋值为源字符串的长度;
  28.  
  29. for(int i=,start=;i<source.length();i++){//注意变量start不要拼写错误!
  30. s[source[i]]++;
  31. // 如果加1后这个字符的数量不超过目标串中该字符的数量,则找到了一个匹配字符
  32. if(s[source[i]]<=t[source[i]]){ //比较源串中的字符是否在目标串中出现过;
  33. found++;//更新出现的字符的个数;
  34. } //为了将目标字符串中出现的字符都包含!
  35.  
  36. // 这一点很重要!!!//
  37. // 如果找到的匹配字符数(只是记录匹配的字符数量)等于目标串长度,说明找到了一个符合要求的子串
  38. // 这一点很重要!!!//
  39.  
  40. if(found==tlength){
  41. //将开头没用的都跳过,没用是指该字符出现次数超过了目标串中出现的次数,并把它们出现次数都减1
  42. while(start<i&&s[source[start]]>t[source[start]]){
  43. s[source[start]]--;
  44. start++;
  45. }
  46. //找到符合要求子串的首尾位置start 与 i, 这时候start指向该子串开头的字母,判断该子串长度
  47. if(i-start<minLen){
  48. minLen=i-start;
  49. beg=start;
  50. end=i;
  51. }
  52. s[source[++start]]--;
  53. found--;//跳过无用的字符后,found减1,然后寻找更短的满足要求的字符串;
  54. }
  55. }
  56. /*如果beg值为-1,说明不存在这样的子串*/
  57. if (beg == -)
  58. return "";
  59. else
  60. return source.substr(beg, end - beg + );
  61. }
  62. };
  63. // 理解时,可以写一个字符串来模拟程序执行过程!

题目有一些难度,参考http://blog.csdn.net/fly_yr/article/details/51134340

应熟练此类题目。

Lintcode--004(最小子串覆盖)的更多相关文章

  1. lintcode 中等题:minimum window substring 最小子串覆盖

    题目 最小子串覆盖 给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的子串. 样例 给出source = "ADOBECODEBANC ...

  2. 最小子串覆盖 · Minimum Window Substring

    [抄题]: 给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的子串. 在答案的子串中的字母在目标字符串中是否需要具有相同的顺序? ——不需要. ...

  3. lintcode-32-最小子串覆盖

    最小子串覆盖 给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的子串. 注意事项 如果在source中没有这样的子串,返回"" ...

  4. 【HDU1960】Taxi Cab Scheme(最小路径覆盖)

    Taxi Cab Scheme Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  5. loj 1429(可相交的最小路径覆盖)

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1429 思路:这道题还是比较麻烦的,对于求有向图的可相交的最小路径覆盖,首先要解决成环问 ...

  6. 【HDU3861 强连通分量缩点+二分图最小路径覆盖】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 题目大意:一个有向图,让你按规则划分区域,要求划分的区域数最少. 规则如下:1.有边u到v以及有 ...

  7. POJ 3216 最小路径覆盖+floyd

    Repairing Company Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 6646   Accepted: 178 ...

  8. POJ3020Antenna Placement(最小路径覆盖+重在构图)

    Antenna Placement Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7788   Accepted: 3880 ...

  9. POJ 3020 (二分图+最小路径覆盖)

    题目链接:http://poj.org/problem?id=3020 题目大意:读入一张地图.其中地图中圈圈代表可以布置卫星的空地.*号代表要覆盖的建筑物.一个卫星的覆盖范围是其周围上下左右四个点. ...

随机推荐

  1. 在网页上看到想要的颜色,如何知道这种颜色的颜色代码和 RGB 颜色值?

    启动QQ的情况下,按截图快捷键(ctrl+alt+A),鼠标移动到要取色的地方即可看到,如下图: references: http://www.zhihu.com/question/20328538

  2. Android 给TextView添加点击事件

    首先设定TextView的clickable属性为true. 可以在布局文件中进行设定,比如: <TextView android:id="@+id/phone" andro ...

  3. GitHub的使用详解!Windows GitHub ,Sublime Git GitGutter的使用!

    Github是什么? 它是代码管理工具. 在公司写的代码,不需要U盘拷贝回家,不需要放到网盘中.只需要上传到git上,就可以回家继续拷贝下来了. 比起svn要好, svn只适合局域网工作,离开局域网, ...

  4. Android 5.0 之SwipeRefreshLayout

    金田 下拉刷新是一种比较常用的效果,Android 5.0之前官方并未提供类似的控件,App中主要是用的第三方库,例如PullToRefresh,ActionBar-PullToRefresh等.刚好 ...

  5. Java中快速排序的实现

    快速排序是对冒泡排序的一种改进.它的基本思想是:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要 小,然后再按次方法对这两部分数据分别进行快速排序,整个排 ...

  6. [HNOI 2013] 消毒 (搜索,二分图匹配)

    题目大意 一个a * b * c(a * b * c <= 5000)大小的长方体中有一些点需要被覆盖,每次可以选择任意大小的长方体,覆盖其中的点,产生的代价为这个长方体长宽高中最小的那个的长度 ...

  7. Shell中特殊的变量

    $表示当前的进程,当使用echo $$是会输出当前shell的pid echo $$ 特殊变量列表 变量 含义 $0 当前脚本的文件名 $n 传递给脚本或函数的参数.n 是一个数字,表示第几个参数.例 ...

  8. JS(五)

    感觉JS里面还是有很多小技巧的,知道套路了,其实实现起来其实也还没有想象中的那么复杂.不过我觉得还是要把所学的知识融会贯通吧,不能学了JS就忘了前面的知识,结合起来才会威力无穷. 1.跑马灯:弹弹弹 ...

  9. 有利于SEO的DIV+CSS规范小结

    一.CSS文件及样式命名 1.CSS文件命名规范 全局样式:global.css:框架布局:layout.css:字体样式:font.css:链接样式:link.css:打印样式:print.css: ...

  10. android Settings 解析

    1.Settings的主界面的实现: Settings采用了PreferenceActivity和PreferenceFragment结合的实现方式. Settings.java继承自Preferen ...