leetcode 76. Minimum Window Substring

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;
    }
};
原文地址:https://www.cnblogs.com/bbbbbq/p/7628086.html