題目地址:Minimum Window Substring
題目簡介:
給定一個字符串 S 和一個字符串 T,請在 S 中找出包含 T 所有字母的最小子串。要求時間複雜度爲O(n)。
示例:
輸入: S = "ADOBECODEBANC", T = "ABC"
輸出: "BANC"說明:如果 S 中不存這樣的子串,則返回空字符串 ""。
如果 S 中存在這樣的子串,我們保證它是唯一的答案。
題目解析:
因爲這個題不需要按照規定的順序,只要找到包含該字符串中所有的字符即可。並且爲了找到最小的字符串,肯定滿足這個子字符串的首尾是目標字符串裏的字符。
這裏使用滑動窗口,即從左邊先找到第一個字符串包含了所有的字符的子字符串,然後依次拋棄這個子字符串的左側字符,並在右側找到對應的字符。例如,例子中首先找到"ADOBEC"滿足條件,然後拋棄'A',組成“BECODEBA”。再拋棄'B',只要找到'C'即可,因爲後面的字符串有'B'。依次下去,找到結果。
C++:
class Solution {
public:
string minWindow(string s, string t) {
if (s == "")
return "";
string ans = "";
int len_s = s.size(), len_t = t.size();
int t_word[128];
memset(t_word, 0 , sizeof(t_word));
int left = 0, cnt = 0, minLen = len_s + 1;
for (char c : t)
++t_word[c];
for (int i = 0; i < len_s; ++i)
{
if (--t_word[s[i]] >= 0)
++cnt;
while (cnt == len_t)
{
if (minLen > i - left + 1)
{
minLen = i - left + 1;
ans = s.substr(left, minLen);
}
if (++t_word[s[left]] > 0)
--cnt;
++left;
}
}
return ans;
}
};
Python:
class Solution:
def minWindow(self, s: str, t: str) -> str:
if s == "":
return ""
ans = ""
len_s = len(s)
len_t = len(t)
t_word = [0 for i in range(128)]
left = 0
cnt = 0
minLen = len_s + 1;
for c in t:
t_word[ord(c)] += 1
for i in range(len_s):
t_word[ord(s[i])] -= 1
if t_word[ord(s[i])] >= 0:
cnt += 1
while cnt == len_t:
if minLen > i - left + 1:
minLen = i - left + 1
ans = s[left:left + minLen]
t_word[ord(s[left])] += 1
if t_word[ord(s[left])] > 0:
cnt -= 1
left += 1
return ans