不好做的一道题,发现String Algorithm可以出很多很难的题,特别是多指针,DP,数学推导的题。参考了许多资料:

http://leetcode.com/2010/11/finding-minimum-window-in-s-which.html

http://www.geeksforgeeks.org/find-the-smallest-window-in-a-string-containing-all-characters-of-another-string/

http://tianrunhe.wordpress.com/2013/03/23/minimum-window-substring/

最有用的最后一个资料,因为里面有一个例子详细说明了如何变化,我加上了一些中文备注:

For example,
S = “ADOBECODEBANC”
T = “ABC”
Minimum window is “BANC”.

Thoughts:
The idea is from here. I try to rephrase it a little bit here. The general idea is that we find a window first, not necessarily the minimum, but it’s the first one we could find, traveling from the beginning of S. We could easily do this by keeping a count of the target characters we have found. After finding an candidate solution, we try to optimize it. We do this by going forward in S and trying to see if we could replace the first character of our candidate. If we find one, we then find a new candidate and we update our knowledge about the minimum. We keep doing this until we reach the end of S. For the giving example:

  1. We start with our very first window: “ADOBEC”, windowSize = 6. We now have “A”:1, “B”:1, “C”:1 (保存在needToFind数组里)
  2. We skip the following character “ODE” since none of them is in our target T. We then see another “B” so we update “B”:2. Our candidate solution starts with an “A” so getting another “B” cannot make us a “trade”. (体现在代码就是只有满足hasFound[S.charAt(start)] > needToFind[S.charAt(start)]) 才能移动左指针start)
  3. We then see another “A” so we update “A”:2. Now we have two “A”s and we know we only need 1. If we keep the new position of this “A” and disregard the old one, we could move forward of our starting position of window. We move from A->D->O->B. Can we keep moving? Yes, since we know we have 2 “B”s so we can also disregard this one. So keep moving until we hit “C”: we only have 1 “C” so we have to stop. Therefore, we have a new candidate solution, “CODEBA”. Our new map is updated to “A”:1, “B”:1, “C”:1.
  4. We skip the next “N” (这里忽略所有不在T的字符:用needToFind[S.charAt(start)] == 0来判断) and we arrive at “C”. Now we have two “C”s so we can move forward the starting position of last candidate: we move along this path C->O->D->E until we hit “B”. We only have one “B” so we have to stop. We have yet another new candidate, “BANC”.
  5. We have hit the end of S so we just output our best candidate, which is “BANC”.
package Level4;

/**
* Minimum Window Substring
*
* Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n). For example,
S = "ADOBECODEBANC"
T = "ABC"
Minimum window is "BANC". Note:
If there is no such window in S that covers all characters in T, return the emtpy string "". If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S. Discuss *
*/
public class S76 { public static void main(String[] args) {
} public String minWindow(String S, String T) {
// 因为处理的是字符,所以可以利用ASCII字符来保存
int[] needToFind = new int[256]; // 保存T中需要查找字符的个数,该数组一旦初始化完毕就不再改动
int[] hasFound = new int[256]; // 保存S中已经找到字符的个数,该数组会动态变化 for(int i=0; i<T.length(); i++){ // 初始化needToFind为需要查找字符的个数,
needToFind[T.charAt(i)]++; // 如例子中T为ABC,则将会被初始化为:needToFind[65]=1, nTF[66]=2, nTF[67]=3
} int count = 0; // 用于检测第一个符合T的S的字串
int minWindowSize = Integer.MAX_VALUE; // 最小窗口大小
int start = 0, end = 0; // 窗口的开始喝结束指针
String window = ""; // 最小窗口对应的字串 for(; end<S.length(); end++){ // 用end来遍历S字符串
if(needToFind[S.charAt(end)] == 0){ // 表示可以忽略的字符,即除了T(ABC)外的所有字符
continue;
}
char c = S.charAt(end);
hasFound[c]++; // 找到一个需要找的字符 if(hasFound[c] <= needToFind[c]){ // 如果找到的已经超过了需要的,就没必要继续增加count
count++;
}
if(count == T.length()){ // 该窗口中至少包含了T
while(needToFind[S.charAt(start)] == 0 || // 压缩窗口,往后移start指针,一种情况是start指针指的都是可忽略的字符
hasFound[S.charAt(start)] > needToFind[S.charAt(start)]){ // 另一种情况是已经找到字符的个数超过了需要找的个数,因此可以舍弃掉多余的部分
if(hasFound[S.charAt(start)] > needToFind[S.charAt(start)]){
hasFound[S.charAt(start)]--; // 舍弃掉多余的部分
}
start++; // 压缩窗口
} if(end-start+1 < minWindowSize){ // 保存最小窗口
minWindowSize = end-start+1;
window = S.substring(start, end+1);
}
}
}
return window;
}
}

Minimum Window Substring @LeetCode的更多相关文章

  1. Minimum Window Substring leetcode java

    题目: Given a string S and a string T, find the minimum window in S which will contain all the charact ...

  2. LeetCode解题报告—— Minimum Window Substring && Largest Rectangle in Histogram

    1. Minimum Window Substring Given a string S and a string T, find the minimum window in S which will ...

  3. 【LeetCode】76. Minimum Window Substring

    Minimum Window Substring Given a string S and a string T, find the minimum window in S which will co ...

  4. 53. Minimum Window Substring

    Minimum Window Substring Given a string S and a string T, find the minimum window in S which will co ...

  5. leetcode76. Minimum Window Substring

    leetcode76. Minimum Window Substring 题意: 给定字符串S和字符串T,找到S中的最小窗口,其中将包含复杂度O(n)中T中的所有字符. 例如, S ="AD ...

  6. 刷题76. Minimum Window Substring

    一.题目说明 题目76. Minimum Window Substring,求字符串S中最小连续字符串,包括字符串T中的所有字符,复杂度要求是O(n).难度是Hard! 二.我的解答 先说我的思路: ...

  7. [LeetCode] Minimum Window Substring 最小窗口子串

    Given a string S and a string T, find the minimum window in S which will contain all the characters ...

  8. leetcode@ [30/76] Substring with Concatenation of All Words & Minimum Window Substring (Hashtable, Two Pointers)

    https://leetcode.com/problems/substring-with-concatenation-of-all-words/ You are given a string, s, ...

  9. [LeetCode] 76. Minimum Window Substring 解题思路

    Given a string S and a string T, find the minimum window in S which will contain all the characters ...

随机推荐

  1. MySqlQueryList

    //辅助查询列表,或实例 public class MySqlQueryList { #region List<T> ToList<T>(string sql, params ...

  2. 关于asp.net 的一些好资料地址 , 防止丢失!

    学习数据结构的好网站 : http://student.zjzk.cn/course_ware/data_structure/web/practice/practice1.htm http://www ...

  3. ThinkPHP常量参考

    常用常量 APP_NAME 当前项目名称 APP_PATH 当前项目路径 GROUP_NAME 当前分组名称 MODULE_NAME 当前Action模块名称 ACTION_NAME 当前操作的名称 ...

  4. PHP的环境搭建

    下载开发环境 wampserver 下载sublime text 2 sublime使用技巧 1:安装漂亮的编程字体http://pan.baidu.com/s/1xMex9 下载"程序编写 ...

  5. kali nessus 安装插件失败解决方法

    code码获取: http://www.tenable.com/products/nessus/select-your-operating-system 首先切换到nessus安装目录下: 1.nes ...

  6. ios 学习笔记(8) 控件 按钮(UIButton)的使用方法

    在实际开发中,对于开发者来说,更多的还是使用“自定义”按钮.将“按钮”对象的类型设置成UIButtonTypeCustom.这样一来,按钮的所有元素都将由开发者来配置和自定义. 对于一个自定义按钮来说 ...

  7. Oracle SQL篇(一)null值之初体验

           从我第一次正式的写sql语句到现在,已经超过10年的时间了.我写报表,做统计分析和财务对账,我一点点的接触oracle数据库,并尝试深入了解.这条路,一走就是10年,从充满热情,到开始厌 ...

  8. 关于struts2的checkboxlist、select等标签发生could not be resolved as a collection/array/map/enumeration/iterator type异常的记录

    1 刚进入该界面的时候发生错误,原因是 list="roles"中的这个集合是空的,导致错误 解决办法很简单,不能让list为空 2 刚进入该界面的时候list是有数据的,当点击提 ...

  9. 将默认首页设置成index.do的方法

    变态欺骗法,今天csdn一个前辈的,学习了,公司服务器是weblogic的,也可以欺骗. 但是我又非常迫切.非常盼望.非常渴望使用index.do做首页,怎么办? Tomcat中用一段注释: When ...

  10. windows上放弃使用PyGTK

    windows上放弃使用PyGTK - riag的专栏 - 博客频道 - CSDN.NET windows上放弃使用PyGTK 分类: python 2010-03-31 16:47 1054人阅读 ...