1. 程式人生 > >leetcode 76. Minimum Window Substring

leetcode 76. Minimum Window Substring

for 所有 targe 端點 cnblogs amp find count leetcode

link

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.

題意:

設T裏的字符i有aim[i]個,在S中求最短子串X, 使得X中的字符i有now[i]個且滿足對任意i有now[i] >= aim[i]。 保證最短的子串只有一個。

思路:

和之前那個concate一個思路,其實也是維護一段窗口內的信息。

變化的地方只在於,裏面有多余的字符也沒有關系。

因此對於右端,一個新加入的字符s[i], 首先肯定是要加進去的。

如果s[i]出現在aim中,則其的加入可能可以使得now[i] > aim[i], 也就是我們可以從左端消除一些字符。 因此用一個while條件判斷左端是否滿足now[s[left]] > aim[s[left]]的條件, 滿足的話刪去左端點是沒有問題的。

在實現的時候偷了個懶,用aim直接計算目前窗口中的數量和目標數量的差距,也就是aim = aim - now。並且只維護起始的aim不為零的部分。那麽while的條件就變為了aim[s[left]] < 0

在統計是否所有的i都成立的時候,註意我們加入一個i的時候有三種情況。

1. i再加一個就滿足了aim[i] <= now[i]的情況。也就是說此時now[i} = aim[i] - 1, 用我們的統計方法也就是aim[i] = 1, 加入後aim[i]恰好變為0

2. i加入多於目標個了,也就是now[i] >= aim[i] , (aim[i] <= 0) 加入 後消除aim等號,變為aim[i] < 0

3 加入i也不夠aim[i], 也就是aim[i] > 0

因此只有在加入i後aim[i]變為0,才能使一個新的i成立。 統計aim中非零的數量,在aim[i] = 0時更新計數器,直至所有i成立,為第一個可行解。當第一個可行解出現後,用我們更新窗口的方法後面的所有情況都是可行的。

code:

class Solution {
public:
    string minWindow(string s, string t) {
        string ans = "";
        int nowMinLength = INT_MAX;
        
        unordered_map<char, int> aim;
        int charCount = 0;
        for(int i = 0; i < t.length(); i++){
            if(aim.count(t[i]) == 0) charCount ++;
            aim[t[i]] ++;
        }
        int left = 0, cnt = 0;
        for(int i = 0; i < s.length(); i++){
            //if(aim.count(s[i]) == 1){
                aim[s[i]] --;
                if(aim[s[i]] == 0) cnt ++;
                while(aim[s[left]] < 0 &&  left < i){
                    aim[s[left]] ++;
                    left ++;
                }
                if(cnt == charCount){
                    int tmpLen = i - left + 1;
                    if(tmpLen < nowMinLength){
                        nowMinLength = tmpLen;
                        ans = s.substr(left, tmpLen);
                    }
                }
            //}
            
        }
        return ans;
    }
};

leetcode 76. Minimum Window Substring