您的位置:首页 > 其它

【LeetCode练习题】Minimum Window Substring

2014-04-01 20:34 344 查看

找出包含子串的最小窗口


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,不要求T的顺序,从S中找出包含T中字符的长度最小的子串,即最小窗口子串。要求算法时间复杂度为O(n)。

解题思路:

这题的考点是两个指针,一个begin在前,一个end在后,当begin和end都包含了T字符串中字符的时候,计算此时begin和end之间的距离,即为一个窗口子串的长度。当end遍历到S的最后时,得到所有算出来的窗口子串中长度最大的那个,即为答案。因为两个指针都从头到尾遍历了一遍,所以时间复杂度是O(n)。

还有一个小技巧就是,怎么才能知道已经包含了所有的字符呢?

可以像桶排序那样,建立一个很大的数组,以T中的字符(ASCI码)为下标的位置设为1,其他为0.

再建立一个很大的数组,遍历S中字符的时候,遍历到一个字符以那个字符为下标设置一个1,当刚好T那个数组中是1的位置对应S的那个数组相应位置全都是非0的时候,就全部包含了T中的字符拉!

至于那个数组多大,就设置为255,包含unicode字符。

代码如下:

#include <iostream>
#include <vector>
#include <string>
using namespace std;

class Solution {
public:
string minWindow(string S, string T) {
vector<int> s_vec(256,0);
vector<int> t_vec(256,0);
int lp = -1, rp = -1, answer = 0x7fffffff, begin = 0, lack = T.size();
//将T中字符对应位置设置成1
for(int i = 0;i < T.size();i++){
t_vec[T[i]]++;
}
for(int end = 0; end < S.size(); end++){
//负责移动右边的i,直到包含了所有T中的字符
if(s_vec[S[end]] < t_vec[S[end]])
lack--;
s_vec[S[end]]++;

if(lack == 0){
//负责移动左边的lb
while( begin < end && s_vec[S[begin]] > t_vec[S[begin]]){
s_vec[S[begin]]--;
begin++;
}
//记录下此时的长度和lb,i的位置
if(answer > end - begin + 1){
answer = end - begin + 1;
lp = begin;
rp = end;
}
//lb向右移一个
while(lack == 0){
s_vec[S[begin]]--;
begin += 1;
lack += 1;
}
}
}
return lp==-1?"":S.substr(lp,rp-lp+1);
}
};

int main(){
Solution s;
string S = "ADOBECODEBANC";
string T = "ABC";
string r = s.minWindow(S,T);
cout << r << endl;
getchar();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: