leetcode_86 Minimum Window Substring

161 篇文章 0 订阅

题目:最小窗口子串

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).

Example:

Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"

Note:

  • If there is no such window in S that covers all characters in T, return the empty string "".
  • If there is such window, you are guaranteed that there will always be only one unique minimum window in S.

Algorithm

  1. We start with two pointers, left and right initially pointing to the first element of the string S.

  2. We use the rightright pointer to expand the window until we get a desirable window i.e. a window that contains all of the characters of T

  3. Once we have a window with all the characters, we can move the left pointer ahead one by one. If the window is still a desirable one we keep on updating the minimum window size.

  4. If the window is not desirable any more, we repeat step2 onwards.

                              

 

The above steps are repeated until we have looked at all the windows. The smallest window is returned.

                      

        算法中使用 count计数 和 hashmap来实现,是否包含所有 字符的功能,统计好t 中的字符及相应个数后, right不断右移,当hashmap值大于0,为t 中的字符,count++,当count值大小为 t 的长度时,所有字符及相应个数已经包含。

       同时,不管字符是否在t 中,也就是 不管hashmap值的多少,相应字符的值都要减1,这样小于0的值,就是窗口中多出来的字符,这些字符一般在窗口前面和中间,前面的可以去除,中间的不用管。

      当找到包含所有字符的窗口时,要检查窗口前端是否有多于字符,使用前面讲述的hashmap小于0的方法,如果有left右移。直到没有多于字符为止,此时窗口的起点为left,长度为 right - left + 1;如果历史窗口最小长度长度大于等于当前最小窗口长度,则更新最小窗口起点位置,和最小窗口长度。    记录好之后,将left 右移,同时恢复hashmap中字符的个数(加1)和已找到字符个数(减1),开始新一轮的循环....

class Solution {
public:
    string minWindow(string s, string t) {
        unordered_map<char,int> tmap;
        int tlen = t.length();
        string res;
        for(int i = 0; i < tlen; i++)
        {
            tmap[t[i]]++;
        }
        int left = 0,right = 0;    /* step 1 */
        int slen = s.length();
        int tcnt = 0;
        int minLen = INT_MAX;
        int minStart = 0;
        while(right < slen)
        {
            if(tmap[s[right]] > 0)     /* step 2 */
                tcnt++;
            tmap[s[right]]--;
            if(tcnt == tlen)
            {
                /* delete unneed prefix  */
                while(left < right && tmap[s[left]] < 0)    /* step 3 */
                    tmap[s[left]]++,left++;
                if(minLen > (right - left))
                {
                    minStart = left;     /* record start */
                    minLen = right - left + 1; /* record len */
                }
                /* find next sub, move left */    /* step 4  */
                tmap[s[left]]++;
                left++;
                tcnt--;
            }
            right++;
        }
        if(minLen == INT_MAX)
            res = "";
        else
            res = s.substr(minStart,minLen);
        return res;
    }
};

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值