【滑动窗口 右指针滑动判断目前窗口内目标元素数量 左指针帮助选最小】 76 最小覆盖子串

题目

给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字符的最小子串。
输入: S = “ADOBECODEBANC”, T = “ABC”
输出: “BANC”

思路

right指针移动,直到window窗口中包含了所有t字符串的元素。
left指针移动,计算每次移动后window的长度,并且用substring方法连接left到right的元素形成输出的字符串。直到window窗口中不包含t的元素,此时回到1步。
直到right到达结尾,结束循环。相当于right是寻找解,left是优化解。

代码

public String minWindow(String s, String t) {
    if(s==null ||s==""||t==null||t==""){
        return "";
    }
    //记录t中每个字符出现的次数
    int []needs = new int[128];
    //记录在滑动窗口总每个字符出现的次数
    int []windows = new int[128];
    for (int i = 0; i < t.length(); i++) {
        needs[t.charAt(i)]++;
    }

    int left = 0;
    int right = 0;
    int minLength = s.length()+1;
    //统计在windows窗口中属于t的字符有几个
    int count = 0;
    //符合输出标准的字符串
    String res = "";
    while(right<s.length()){
        char ch = s.charAt(right);
        windows[ch]++;
        //ch这个元素在need中是有的
        //如果s中有重复的t元素,不能盲目累加。
        //当t中的当前元素个数大于等于s中的时候,再计数
        if(needs[ch]>0&&needs[ch]>=windows[ch]){
            count++;
        }
        while(count==t.length()){
            ch = s.charAt(left);
            if(needs[ch]>0&&needs[ch]>=windows[ch]){
                count--;
            }
            if(right-left+1<minLength){
                minLength = right-left+1;
                res = s.substring(left,right+1);
            }
            windows[ch]--;
            left++;
        }
        right++;
    }
    return res;

你可能感兴趣的:(滑动窗口,字符串)