leetcode 最小覆盖子串

 滑动窗口的经典范例,具体解法已在算法思想的滑动窗口中阐述,贴个解答代码。

 

public String minWindow(String s, String t) {
        Map<Character,Integer> need=new HashMap<>();    //子串窗口
        Map<Character,Integer> window=new HashMap<>();   //滑动窗口
        char [] sCharArrays=s.toCharArray();
        char [] tCharArrays=t.toCharArray();
        for(char c:tCharArrays){
            need.put(c,need.getOrDefault(c,0)+1);    //用hashmap记录出现字母的次数
        }

        int left=0,right=0;
        int valid=0;
        int length=Integer.MAX_VALUE;
        int start=0;

        while(right<s.length())              //右指针滑动
        {
            char c=sCharArrays[right];          //right划过窗口的元素
            right++;
            if(need.containsKey(c))        //如果是是子串的组成字母之一,加入滑动窗口
            {
                window.put(c,window.getOrDefault(c,0)+1);  
                if(window.get(c).equals(need.get(c)))       //如果该字母数目在滑动窗口和子串窗口中相同,valid++
                    valid++;
            }

        
            while(valid==need.size())           //当所有的字母在window和need中出现次数相同,开始收缩窗口
            {   
                if(right-left<length)
                {
                    length=right-left;
                    start=left;
                }
                char d=sCharArrays[left];           //left划出的元素
                left++;
                if(need.containsKey(d)){                    
                    if(window.get(d).equals(need.get(d)))   //注意:在这里只能写.equals(),不能写==
                        valid--;                            //  因为这里是Integer对象之间的比价,如果超过
                    window.put(d,window.get(d)-1);          //-128-127会重新new一个对象使==报错。(上面的equals同)
                }
                    
            }
        }
        if(length==Integer.MAX_VALUE) return "";
        return s.substring(start,start+length);
        
    }
    

 

 

posted @ 2021-08-11 15:39  毅毅毅毅毅  阅读(31)  评论(0)    收藏  举报