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.
给定一个字符串S和一个目标串T,求出在S中包含T中所有字符(包括个数)的最短子串。
O(n)
维护两个map,一个记录T中所有出现过的字符及其个数 source
另一个map记录所有T中出现过的字符,个数初始化为0 count
扫描S串
如果当前字符没有在T中出现过,跳过
如果出现过:如果当前在count中该字符的个数已经大于等于目标串中该字符的个数,则count值加1
如果在当前count中该字符的个数小于目标串中该字符的个数,则count对应的值加1,并且判断当前的count是否都比source中的值大于或者等于。如果valid,则根据count来截取字符串:
过程为:
从left向右扫,left记录上一个不valid的位置,即初始为0
如果S[left]在T中没有出现过,跳过,left++
如果S[left]在T中出现过,则更新最短字符串, left++, count中该字符对应的值减1。当count中该字符对应的个数比source中小时,不再valid,跳出循环,从right继续向右扫描。
class Solution {
public:
map<char,int> count;
map<char,int> source;
bool valid(){
for(map<char,int>::iterator it = count.begin();it!=count.end();++it){
map<char,int>::iterator it2 = source.find(it->first);
if(it->second<it2->second)
return false;
}
return true;
}
string minWindow(string S, string T) {
string mi = "";
int left = 0;
int right = 0;
int n = S.length();
for(int i=0;i<T.length();i++){
map<char,int>::iterator it = source.find(T[i]);
if(it==source.end()){
count.insert(pair<char,int>(T[i],0));
source.insert(pair<char,int>(T[i],1));
}else{
it->second++;
}
}
for(int right=0;right<n;right++){
if(source.find(S[right])!=source.end()){
map<char,int>::iterator it1 = source.find(S[right]);
map<char,int>::iterator it2 = count.find(S[right]);
if(it1->second <= it2->second){
it2->second++;
}else{
it2->second++;
if(valid()){
while(left<=right){
it2 = count.find(S[left]);
if(it2==count.end()){
left++;
continue;
}
it1 = source.find(S[left]);
if(it2->second>=it1->second){
if(mi=="")
mi = S.substr(left,right-left+1);
else
mi = (right-left+1)<mi.length()?S.substr(left,right-left+1):mi;
it2->second--;
left++;
if(it2->second<it1->second)
break;
}else{
break;
}
}
}
}
}
}
return mi;
}
};
==============================================2014/10/26=====================================
以前的代码写的真是弱,能回过头来重新写一遍,而且写的更好,也是进步,鼓励一下自己
class Solution {
public:
map<char,int> cnt;
string minWindow(string S, string T) {
for(int i=0;i<T.length();i++){
map<char,int>::iterator it = cnt.find(T[i]);
if(it==cnt.end())
cnt.insert(pair<char,int>(T[i],1));
else
it->second++;
}
int start = -1,length = 50000;
int m = cnt.size();
int slow = 0,fast = 0;
int n = S.length();
while(fast<n){
map<char,int>::iterator it = cnt.find(S[fast++]);
if(it!=cnt.end()){
it->second--;
if(it->second==0)
m--;
if(m==0){
while(slow<fast){
it = cnt.find(S[slow]);
if(it!=cnt.end()){
if(fast-slow<length){
start = slow;
length = fast-slow;
}
it->second++;
if(it->second>0){
m++;
slow++;
break;
}
}
slow++;
}
}
}
}
if(start!=-1)
return S.substr(start,length);
return "";
}
};