题目描述:
给定一个字符串source和一个目标字符串target,在字符串source中找到包括所有目标字符串字母的子串。
注意事项:
如果在source中没有这样的子串,返回”“,如果有多个这样的子串,返回起始位置最小的子串。
说明:
在答案的子串中的字母在目标字符串中是否需要具有相同的顺序?
——不需要。
样例:
给出source = “ADOBECODEBANC”,target = “ABC” 满足要求的解 “BANC”
思路讲解:
我们首先将目标字符串映射到一个大小为128的hash_target数组,然后我们建立一个同样的hash数组,然后遍历source这个字符串,并用两个指针begin和end,每次都将字符与target的没以恶搞字符比较,然后将其在hash中对应的位置加一,并将其与hash_target比较,如果是,则说明找到一个子串可以包含target的,然后我们将从begin开始,逐个删除字符(这一步是为了得到最小的子串包含target的),如果删除之后,hash还是比hash_target大,说明找到了一个较小的子串;如果没有就从end开始继续遍历source,这样就可以得到了最小的子串。
举个栗子:
ADOBECODEBANC
a.当begin=0时,hash为空,显然不满足子串,则将end后移直至end=5时。此时hash的计数为A=1,B=1,C=1,满足子串要求,此时最小子串为ADOBEC,长度为6。最后将A的计数减1,此时hash的计数为A=0,B=1,C=1。
b.当begin=1时,由于hash不满足子串要求,则继续步骤a直至end=10。此时hash的计数为A=1,B=2,C=1,最小子串为DOBECODEBA,长度为10。然后将D去掉,此时hash的计数为A=1,B=2,C=1。
c.当begin=2时,最小子串为OBECODEBA,直至begin=6时,hash的计数为A=1,B=2,C=0,将end继续向后移动至最后一位,hash重新满足子串要求。再继续重复上述步骤可获取最小子串。
代码详解:
class Solution {
public:
/*
* @param source : A string
* @param target: A string
* @return: A string denote the minimum window, return "" if there is no such a string
*/
string minWindow(string &source , string &target) {
// write your code here
int length=target.length();
if(source=="")
return "";
vector<int> hash(128,0);
vector<int> hash_target(128,0);
for(int i=0;i<length;i++)//初始化target的映射
{
hash_target[target[i]]++;
}
int begin,end;
begin=0,end=0;
int sublength=INT_MAX,low=0,high=0;
while(end<source.length())
{
if(!judge_contain_target(hash,hash_target))//如果没有找到子串,就继续找
{
for(int i=0;i<length;i++)
{
if(target[i]==source[end]){
hash[target[i]]++;
break;
}
}
end++;
}
if(judge_contain_target(hash,hash_target)){//如果找到子串,就看是否存在较短的子串
if(sublength>(end-begin)){
sublength=end-begin;
low=begin;
high=end;
}
for(int i=0;i<length;i++)
{
if(target[i]==source[begin]){
hash[target[i]]--;
break;
}
}
begin++;
}
}
while(judge_contain_target(hash,hash_target))//特殊情况的处理例如:aaaaaaaabcd和abcd
{
if(sublength>(end-begin)){
sublength=end-begin;
low=begin;
high=end;
}
for(int i=0;i<length;i++)
{
if(target[i]==source[begin]){
hash[target[i]]--;
break;
}
}
begin++;
}
if(sublength==INT_MAX){
return "";
}
else{
return source.substr(low,sublength);
}
}
bool judge_contain_target(vector<int>hash,vector<int>hash_target)//判断是否找到了子串
{
for(int i=0;i<128;i++)
{
if(hash[i]<hash_target[i]){
return false;
}
}
return true;
}
};