1. 程式人生 > 其它 >Minimum Window Substring

Minimum Window Substring

題目描述

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);
    }
};