76. 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 empty string ""
.
If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in S.
class Solution {
public:
string minWindow(string s, string t) {
vector<int> map(128,0);//初始化map哈希表,全部为0
//根据给定的T,将里面相应的子母在哈希表中计数为1
for(int i=0;i<t.size();i++)
map[t[i]]++;//t中出现的子母全部变成1
//初始化双指针和计数、长度
int start=0;//起始指针
int end=0;//终止指针
int count=t.size();//计数,初始化为模式字符串的长度
int d=numeric_limits<int>::max();//初始化结果的长度为最大
int head=0;//这个head当前找到满足要求的双指针范围中,出现的第一个在t中的字符位置,因为start会更新的
//下面进行正式的遍历,只遍历一遍
//首先考虑我们所期望的过程:从在s中找到第一个t中的子母开始,count--,直到找到最后一个t钟出现的字符,count变成0,当一个t中的字符找到之后,他的map计数值变成0,处理count语句应该只当map[i]==1的时候才减一。最后end指向当前最后一个子串的下一个位置。
//找到子串之后,可能出现这种情况:因为start一直指向0位置,所以可能第一个符合要求的字符在0位置后面,现在的子串包含前面一段无用子串,需要设置循环,缩小到第一个满足要求的字符(t中的字符)。同时更新最小长度。跳出循环。
while(end<s.size())
{
if(map[s[end++]]-->0) count--;
/*if(map[s[end]]>0)
{
count--;//找到一个t中字符,count自减,然后将这个出现的字符map减1变成0
map[s[end]]--;
end++;
}*///这种写法不行,因为加和-操作不管条件是否满足都要进行
//简化版本: if(map[s[end++]]-->0) count--;
while(count==0)//能够进入循环,说明目前end和start指向的区间范围,包含了所有的t中子母,这个时候end指向最后一个子母的下一个,这个循环不断的缩减长度,知道begin指向第一个出现的t字符,
{
if(end-start<d) d=end-(head=start);//只有在需要更新的时候才同时更新head
if(map[s[start++]]++==0) count++;//这一段之前已经操作过一遍,由于t中的字符开始的时候大1,所以第一个等于0的一定是出现的第一个t中的字符,当找到t字符时,start指向第一个字符的下一个位置。end指向最后一个字符的下一个位置。之前最后一次计算的值正好是正确的长度
//保存head的原因是,后面进入到外循环时,不一定再找到另外一个满足要求的字符串
//下面在寻找另外一个字符串,这个时候count是1,只要找到另外一个之前之前start找到的字符即可(相当于把之前的那个字符舍弃了)
}
}
return d==numeric_limits<int>::max()?"":s.substr(head,d);//有可能没找到
}
};
整体思路:
int findSubstring(string s){
vector<int> map(128,0);
int counter;
//检查字符串是否是有效的
int begin=0, end=0; //two pointers, one point to tail and one head
int d; //the length of substring 子字符串长度
for() { /* initialize the hash map here 初始化哈希表 */ }
while(end<s.size()){
if(map[s[end++]]-- ?){ /* 根据更新计数值*/ }
while(/* 达到计数值条件*/){
/* */
//increase begin to make it invalid/valid again
if(map[s[begin++]]++ ?){ /*modify counter here*/ }
}
/* update d here if finding maximum,最大值在外边进行*/
}
return d;
}