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.
算法思想:通过建立hash表unordered_map来记录扫描过的元素,并且记录其重复个数。因为S只能遍历一遍,所以还需要两个指针去限制最终包含区域的范围,即first与behind。且还需要一个count去记录每次循环过程中是否达到了包含字符串T的条件。具体代码如下:
string minWindow(string S, string T) {
string result;
if (S.empty() || T.empty())
return result;
unordered_map<char, int> m1; //建立<char,int>类型的hash表,方便记录重复元素
unordered_map<char, int> m2;
for (int i = 0; i < T.length(); i++)
m1[T[i]]++; //记录target中每个元素的个数
int first = 0, behind = 0;//用两个指针去维护字符串S
int count=0;//监控器
int minlength = INT_MAX;
for (; first < S.length(); first++) {
if (m1.find(S[first]) != m1.end()) {
m2[S[first]]++;
if (m2[S[first]] <= m1[S[first]]) // 元素重复不能比待匹配串多
count++;
}
if (count >= T.length()) {
while (m1.find(S[behind]) == m1.end() || m2[S[behind]]>m1[S[behind]]) { //当出现查找不到或者m2的某元素已经多余m1的这个元素时
m2[behind]--;
behind++; //向后移一位
}
if (first - behind + 1 < minlength) { //遇到更短的区间时更新
minlength = first - behind + 1;
result = S.substr(behind, minlength);
}
}
}
return result;
}