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 empty string ""
.
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
我们最开始先扫描一遍T,把对应的字符及其出现的次数存到哈希表中。
然后开始遍历S,遇到T中的字符,就把对应的哈希表中的value减一,直到包含了T中的所有的字符,纪录一个字串并更新最小字串值。
将子窗口的左边界向右移,略掉不在T中的字符,如果某个在T中的字符出现的次数大于哈希表中的value,则也可以跳过该字符。
代码:
public class Solution { public String minWindow(String s, String t) { HashMap<Character,Integer> tmap = new HashMap<Character,Integer>(); char[] tc = t.toCharArray(); for(int i=0;i<tc.length;i++){ //将t转为数组后每一个字母作为键值放到hashmap中,出现的次数是其value值 if(tmap.containsKey( tc[i] )){ tmap.put( tc[i],tmap.get(tc[i])+1 ); } else{ tmap.put( tc[i],1 ); } } int left = 0,scond = 0; int count = 0; String ans = ""; int minlen = s.length()+1; char []sc = s.toCharArray(); for(int right = 0;right<s.length();right++){ char rc = sc[right]; //right 对应的字符串 if(tmap.containsKey( rc ) ){ tmap.put( rc,tmap.get(rc)-1 );//窗口中出现一次该字母 ,value值-- if( tmap.get(rc) >=0 ) //当在窗口中出现的次数小于在t中出现的次数时=,说明还不多于 count++; while(count == t.length()){ // 当count等于t的长度时,做两件事,一left右移动,跳过不在t中出现的字符,或者出现次数多于t的 if( right-left+1 < minlen ){ //二:判断并更新最小窗口的值 和ans ans = s.substring(left,right+1); minlen = right-left+1; } char lc = sc[left]; //left对应的字符串 if( tmap.containsKey( lc ) ){ tmap.put( lc,tmap.get( lc )+1 ); if(tmap.get( lc ) >0 ) count--; } left++; } } } return ans; } }