力扣76.最小覆盖字串

class Solution {
    public String minWindow(String s, String t) {
        if(s == null || t == null || s.length() == 0 || t.length() == 0) return "";
        int matchCount = 0;
        String res = "";
        int[] tArr = new int[256];
        //记录t中元素和出现的个数
        for(char c: t.toCharArray()){
            tArr[c]++;//字符的ASCII作为index
        }

        int[] sArr = new int[256];
        int left = findNextStrIdx(0, s, tArr);
        if(left == s.length()) return "";//遍历完都没有
        int right = left;
        while(right < s.length()){
            int rightChar = s.charAt(right);   //找出相同的这个字符 
            if(sArr[rightChar] < tArr[rightChar]){//如果相等matchCount不+1
                matchCount++;//匹配总次数+1
            }
            sArr[rightChar]++;//该字符次数+1
            //如果找到一个解,更新res值,这个时候要移动left
            while(left < s.length() && matchCount == t.length()){
                if(res.isEmpty() || res.length() > right - left + 1){
                    res = s.substring(left, right + 1);
                }
                int leftChar = s.charAt(left);
                if(sArr[leftChar] <= tArr[leftChar]){//如果大于,还是匹配的,matchCount不变
                    matchCount--;
                }
                sArr[leftChar]--;//leftChar出的字符次数要-1
                left = findNextStrIdx(left + 1, s, tArr);//left移到下一个t中包含的字符
            }
            //还未找到,找到下一个匹配的字符
            right = findNextStrIdx(right + 1, s, tArr);//移到下一个t中包含的字符
        }
        return res;

    }

    public int findNextStrIdx(int start, String s, int[] tArr){
        //遍历s中每一个字符,如果该字符是t中包含的,返回这个字符
        while(start < s.length()){
            char c = s.charAt(start);
            if(tArr[c] != 0) return start;
            start++;
        }

        return start;
    }
}

归纳:
在这里插入图片描述
先遍历s,找到所有匹配的元素,定位left,移动right指针,计算每次元素出现的次数和总的match数(注意两者区别),match数达到target后,再移动left指针,找出最短的匹配字串,如果不满足match数,left不动,再移动right使match重新满足,再移动left…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值