Minimum Window Substring
阿新 • • 發佈:2022-12-10
題目描述
Given two strings s and t of lengths m and n respectively, return the minimum window substring of s such that every character in t (including duplicates) is included in the window. If there is no such substring, return the empty string "".
The testcases will be generated such that the answer is unique.
A substring is a contiguous sequence of characters within the string.
輸入描述
輸入滿足以下條件:
- m == s.length
- n == t.length
- 1 <= m, n <= 105
- s and t consist of uppercase and lowercase English letters.
示例
輸入
s = "ADOBECODEBANC", t = "ABC"
輸出
"BANC"
解釋
The minimum window substring "BANC" includes 'A', 'B', and 'C' from string t.
分析
顯然,可以通過列舉區間的起點和終點暴力解決這個問題,但時間複雜度過高,是否存在一種只需遍歷一遍字串就能得到結果的方法呢?
利用滑動視窗的思想,就可以掃描一遍字串求解該問題。
本題的滑動視窗解法的偽碼如下:
string s, t; // 在 s 中尋找 t 的「最小覆蓋子串」 int left = 0, right = 0; string res = s; while(right < s.size()) { window.add(s[right]); right++; // 如果符合要求,說明視窗構造完成,移動 left 縮小視窗 while (window 符合要求) { // 如果這個視窗的子串更短,則更新 res res = minLen(res, window); window.remove(s[left]); left++; } } return res;
目前已經明確了可以通過一遍掃描字串解決問題,那該如何高效的判斷當前視窗是否滿足要求就成為了問題的關鍵。我們可以維護一個字典來實現滿足要求的判定。
AC程式碼
class Solution
{
public:
string minWindow(string s, string t)
{
unordered_map<char, int> tm;
for (auto i : t)
tm[i]++;
int l = 0, r = 0;
int ansl, len = -1, cnt = 0;
while (r < s.size())
{
if (tm.find(s[r]) != tm.end())
{
if (tm[s[r]] > 0)
cnt++;
tm[s[r]]--;
}
while (cnt == t.size() && l <= r)
{
if (len == -1 || len > r - l + 1)
{
len = r - l + 1;
ansl = l;
}
if (tm.find(s[l]) != tm.end())
{
if (tm[s[l]] >= 0)
cnt--;
tm[s[l]]++;
}
l++;
}
r++;
}
return len == -1 ? "" : s.substr(ansl, len);
}
};