滑动窗口--最小覆盖子串 76

给了字符串s和t,输出包含所有t中字符(注意是所有,1个字母有两次要输出两次)的最小长度的s的子串

如果要求最长,则while一直加end加到不符合条件,开始增加start直到符合条件,之后再开始增加end直到最后。
如果要求最短,则while一直循环加end到符合条件,开始增加start直到不符合条件,之后再开始增加end直到最后。
如果要符合某个条件有三种情况时,不要把增加写到第一步,因为不确定如果此时符合一种条件时该不该加,两种情况的话好说因为不是你就是我,但是三种有可能有的不能加。
然后初始的left和right都可以是0,然后while的循环条件为right<s.size()
进入循环后首先保存此时要添加的值,右移窗口,然后进行窗口数据更新,接着用一个while循环判断左侧窗口是否要收缩,如果要收缩,则首先保存此时要删掉的数据,然后start右移,接着进行窗口数据更新
这是一个左闭右开窗口。

class Solution {
        HashMap<Character,Integer> map1=new HashMap<>();//t中的所有字符次数的map
        HashMap<Character,Integer> map2=new HashMap<>();//窗口中所有字符次数的map
    public String minWindow(String s, String t) {
        int sl=s.length();
        int tl=t.length();
        char[] S=s.toCharArray();
        char[] T=t.toCharArray();
        for(int i=0;i<tl;i++){
            map1.put(T[i],map1.getOrDefault(T[i],0)+1);       
        }
        int start=0;
        int end=0;
        int min=Integer.MAX_VALUE;
        int res1=-1,res2=-1;
        while(end<sl){
            char c=S[end];
            end++;
            if(map1.containsKey(c)){
                 map2.put(c,map2.getOrDefault(c,0)+1);
            }
            while(check()){
                 if(end-start<min){
                    min=end-start;
                    res1=start;
                    res2=end;
                }
                char d=S[start];
                start++;
                if(map1.containsKey(d)){
                  map2.put(d,map2.getOrDefault(d,0)-1);
                }
            }
        }
        return res1==-1?"":s.substring(res1,res2);
    }
     public boolean check() {//遍历所有的字符串t,看现在窗口中是否包含。
        Iterator iter = map1.entrySet().iterator(); 
        while (iter.hasNext()) { 
            Map.Entry entry = (Map.Entry) iter.next(); 
            Character key = (Character) entry.getKey(); 
            Integer val = (Integer) entry.getValue(); 
            if (map2.getOrDefault(key, 0) < val) {
                return false;
            }
        } 
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值