leetcode 76. 最小覆盖子串-java实现

题目所属分类

滑动窗口算法 属于双指针算法中的一个小范围
和这道题类似

leetcode 30. 串联所有单词的子串-java详细版本

可以对比着看

原题链接

给你一个字符串 s 、一个字符串 t 。返回 s 中涵盖 t 所有字符的最小子串。如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 “” 。

注意:

对于 t 中重复字符,我们寻找的子字符串中该字符数量必须不少于 t 中该字符数量。
如果 s 中存在这样的子串,我们保证它是唯一的答案。

代码案例:输入:s = “ADOBECODEBANC”, t = “ABC”
输出:“BANC”

题解

leetcode 76. 最小覆盖子串-java实现_第1张图片

class Solution {
    public String minWindow(String s, String t) {
         HashMap<Character,Integer> hs = new HashMap<Character,Integer>();//滑动窗口
         HashMap<Character,Integer> ht = new HashMap<Character,Integer>();//t的哈希
         for(int i = 0;i < t.length();i ++){
            ht.put(t.charAt(i),ht.getOrDefault(t.charAt(i), 0) + 1);
        }
        String ans = "";
        int cnt = 0 ;//统计有效字符的个数
        for(int i = 0 , j = 0; i < s.length() ; i ++){
            hs.put(s.charAt(i),hs.getOrDefault(s.charAt(i), 0) + 1);
            //有效字符 判断i是不是合法也算上
            if(ht.containsKey(s.charAt(i))&&hs.get(s.charAt(i)) <= ht.get(s.charAt(i))) cnt ++;
            //维护双指针 判断j是不是多余的
            while(j < i && (!ht.containsKey(s.charAt(j))||hs.get(s.charAt(j)) > ht.get(s.charAt(j)))){
                hs.put(s.charAt(j),hs.get(s.charAt(j)) - 1);
                j++;
            }
            //如果cnt==t的长度了,并且(res长度可以更新,或者res还没有赋值)
            if(cnt == t.length() && (ans.length() > (i-j+1 ) || ans.isEmpty() )){
                    ans = s.substring(j , i + 1) ;
            }
        }
        return ans ;
    }
}
class Solution {
    public String minWindow(String s, String t) {
        HashMap<Character,Integer> hs = new HashMap<Character,Integer>();//存s字符串的哈希表 滑动窗口
        HashMap<Character,Integer> ht = new HashMap<Character,Integer>();//存t字符串的哈希表
        for(char a : t.toCharArray() ) {//向哈希表ht中计数
            ht.put(a,ht.getOrDefault(a,0)+1);       
        }
        String res = "" ;
        int cnt = 0 ; 
        for(int i = 0, j = 0  ; i < s.length() ; i++){
            hs.put(s.charAt(i),hs.getOrDefault(s.charAt(i),0)+1);//向哈希表hs中计数
            //滑动窗口向右移动的时候 多加入一个字符 使得hs小与等于ht里面的字符个数 这样的叫做有效字符
         if(  hs.get(s.charAt(i)) <= ht.getOrDefault(s.charAt(i),0)) cnt ++;//有效计数加一
          // if( ht.containsKey(s.charAt(i)) && hs.get(s.charAt(i)) <= ht.get(s.charAt(i))) cnt ++;
            //开始滑动窗口左边的j移动 反过来的话 滑动窗口就需要移动了 记得此时是j向右移动
            while( j < i && hs.get(s.charAt(j)) > ht.getOrDefault(s.charAt(j),0)) {
                 hs.put( s.charAt(j) ,hs.get(s.charAt(j))-1);j++;
            }
           
               
            if(cnt == t.length()){
                if(res.isEmpty() || i - j + 1 < res.length() )
                 res =  s.substring(j , i + 1);
            }

        }
        return res ;
    }
}

你可能感兴趣的:(LeetCode,java,leetcode,算法)