最小子串覆蓋
給定一個字符串source和一個目標字符串target,在字符串source中找到包括所有目標字符串字母的子串。
注意事項
如果在source中沒有這樣的子串,返回"",如果有多個這樣的子串,返回起始位置最小的子串。
說明
在答案的子串中的字母在目標字符串中是否需要具有相同的順序?
——不需要。樣例
給出source = "ADOBECODEBANC",target = "ABC" 滿足要求的解 "BANC"
挑戰
要求時間復雜度為O(n)
標簽
領英 哈希表 臉書
思路
采用哈希映射記錄字符串中每個字母出現的次數,字符ASCII碼有128個,所以用大小為128位的數組記錄字符串中每個字母出現的次數,如countSource['A']表示A出現的次數,而不是用countSource[0]表示。
先用countTarget數組記錄target中每個字符出現的次數,用begin,end記錄最小子串覆蓋(MVS)在source中的起始位置和結束位置,之后遍歷source。
code
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 sizeSource = source.size(), sizeTarget = target.size();
if(sizeSource == 0) {
return string("");
}
int i, countSource[128], countTarget[128];
for(i=0; i<128; i++) {
countSource[i] = 0;
countTarget[i] = 0;
}
for(i=0; i<sizeTarget; i++) {
countTarget[target[i]]++;
}
int begin = -1, end = sizeSource, start = 0, found = 0, minLen = sizeSource;
for(i=0,start=i; i<sizeSource; i++) {
countSource[source[i]]++;
if (countSource[source[i]] <= countTarget[source[i]]) {
found++;
}
if (found == sizeTarget) {
while (start < i && countSource[source[start]] > countTarget[source[start]]) {
countSource[source[start]]--;
start++;
}
if (i - start < minLen) {
minLen = i - start;
begin = start;
end = i;
}
countSource[source[start++]]--;
found--;
}
}
if (begin == -1) {
return string("");
}
else {
return source.substr(begin, end - begin + 1);
}
}
};