Leetcode 76. Minimum Window Substring 最小子串窗口 解题报告

1 解题思想

这题是说在S串当中,找出一个最小的窗口,这个窗口正好包含了T中的所有字符。其中在S当中只要包含了T的所有字符(包括出现的次数也要满足)就可以了,可以有多余的字符,顺序也不限制。

基本思想就是用两个指针,和一个计数Hash表,用来计数是否满足,然后滑动。。。具体的解法,看我留在代码里的注释,写的很详细,这里就不复述了

2 原题

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.

3 AC解

public class Solution {
    /**
     * 两个指针,哈希表保存当前经过的数组。。。
     * 经过的字符,如果包含在T中,那么对应的计数-1,使用count表示有效计数(也就是T的长度),当计数减去后大于等于0的(注意可以小于0),就证明T中还有有待匹配的,那么count也跟着减,当count=0的时候p-q之间肯定有答案。
     * 如果p-q之间,正好满足了T的要求,那么就按照长度进行更新就可以。。。注意p的位置要记得调整到合适的,此时将p调整到第一个count不为0之前,如何确定count不为0,之前不是有计数的么,那么p在前进过程中,如果遇到T中没有的额就直接前进,如果遇到的是T包含的,但是计数小于0,那么p也可以继续前进,只需将对应的字符计数++就可以。
     * 
     */
    public String minWindow(String s, String t) {
        char S[]=s.toCharArray();
        char T[]=t.toCharArray();
        String result="";
        //字符计数,只记录T里面的,并且做一个初始的技术
        HashMap<Character,Integer> map=new HashMap<Character,Integer>();
        for(int i=0;i<T.length;i++){
            if(map.containsKey(T[i])==false){
                map.put(T[i],0);
            }
            map.put(T[i],map.get(T[i])+1);
        }
        int count=T.length,p=0,q=0;  //注意count是必须要匹配的个数
        //移动q
        while(q<S.length){
            /**
             * 如果q对应的位置的S的字符,在T中出现,那么计数-1
             * 注意有效的count--是需要剪完后仍然大于0的,也就是还满足T的要求的
             * */
            if(map.containsKey(S[q])){
                int tmp=map.get(S[q]);
                if(tmp>0)
                    count--;
                map.put(S[q],tmp-1);
            }
            q++;
            //count=0的时候证明,已经有了能匹配T的字串了,此时移动p,到刚好能满足这个位置q的最小位置就可以
            if(count==0){
               while(p<q && count==0){
                   if(map.containsKey(S[p])==true){
                       int tmp=map.get(S[p]);
                       if(tmp>=0){
                           if(result.equals("") || result.length()>=q-p){
                               result=s.substring(p,q);
                           }
                           count++;
                       }
                      map.put(S[p],tmp+1);
                   }
                   p++;
               }
            }
        }
        return result;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值