您的位置:首页 > 其它

[leetcode]Minimum Window Substring

2017-05-21 20:13 465 查看
Minimum Window Substring

Difficulty:Hard

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.

题目就是要在S中找到包含T中所有字符的最短子串,包含即可不需要顺序也相同,要求时间复杂度O(n)。

一开始想了几个方法复杂度都不是O(n),想了很久才想出一个办法。

先用一个数组compare记录T中所有字符的重复次数,即ASCii码从33到126的范围内计算,一共93种字符,例如T="aab<"就是2个a、1个b和一个<。

另一个数组match记录当前已满足的字符数,当match中所数都大于等于compare的时候就是找到了一个匹配

例外还有一个链表matchStr记录满足的字符的位置,当match中所有数没有都大于等于compare的时候,其中match大于compare的数就是有多余的字符,应该尽可能的去除这些字符,但是只能从链表的头部开始去除。

当找到了一个匹配后,通过删除去除满足字符的头,让匹配继续往后找。

string minWindow(string s, string t) {

int start = -1;
int end = s.size()+1;//end一开始大于S的size保证第一次匹配时能够赋值
vector<int> compare(93, 0);//需要满足的字符串个数
vector<int> match(93, 0);//已经满足的字符串个数
list<pair<int, char>> matchStr;//满足的字符串

for (int i = 0; i < t.size(); i++){ //计算每个字符需要的数量
compare[(int)(t[i]-33)]++;
}
for (int i = 0; i < s.size(); i++){
if (t.find(s[i]) != t.npos){//判断当前字符是否包含在T中

pair<int, char> p(i, s[i]);//加入满足队列
matchStr.push_back(p);

match[(int)(s[i] - 33)]++;//满足数增加

while (match[(int)(matchStr.front().second - 33)]>compare[(int)(matchStr.front().second - 33)]){//从头开始去除超出的满足字符
match[(int)(matchStr.front().second - 33)]--;
matchStr.pop_front();
}

bool isMatch = true;
for (int j = 0; j < match.size(); j++){//判断当前是否包含足够的字符
if (match[j] < compare[j])
isMatch = false;
}
if (isMatch){//包含足够的字符
if (i - matchStr.front().first < end - start){//是否比已找到的子串更短
start = matchStr.front().first;
end = i;
}

match[(int)(matchStr.front().second - 33)]--;//去除满足字符的头,让匹配继续往后找
matchStr.pop_front();

while (match[(int)(matchStr.front().second - 33)]>compare[(int)(matchStr.front().second - 33)]){//再从头开始去除超出的满足字符
match[(int)(matchStr.front().second - 33)]--;
matchStr.pop_front();
}

}
}
}

if (start < 0 )//通过start判断是否有找到匹配
return "";
else
return s.substr(start, end - start + 1);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: