算法——滑动窗口之最小覆盖子串

8.最小覆盖子串

题目:. - 力扣(LeetCode)

我们很容易就能想到暴力解法,就是暴力枚举:

我们找到满足条件的这个子串后,就要将left++,然后right回到left的位置开始遍历,寻找下一个满足条件的子串,期间用哈希表来统计,判断是否满足条件

我们在暴力解法上进行优化:

(1)实际上当找到一个满足条件的子串后,right没必要回到left的位置,因为哈希表中已经存有left到right的信息

(2)left不只是简单的++,因为left++后,可能会出现2种情况:

①子串还是满足条件,那么left还要继续++,

②子串不满足条件,那么left不用在继续++

因此这种双指针同向运动的题目就是我们熟悉的滑动窗口

我们用in来表示进窗口的元素,out来表示出窗口的元素,hash1记录t中每个字符的个数,hash2记录窗口中每个字符的个数

(1)进窗口:hash2(in)++

(2)判断 :判断hash1和hash2中记录的字符情况是否一致,是的话更新结果,并出窗口

(3)出窗口:hash2(out)++

对于判断的优化:我们在前面的题目做过类似的判断优化方法,即用count来记录有效字符的个数

但是在这道题中两个哈希表不是简单的一一对应的关系,hash2中的字符可能会出现多次

所以我们应该判断的是字符的种类,即当hash1[in] == hash2[in]时,count++;而用kinds记录t中字符的种类,当kinds == count时,更新条件

题解:

java 复制代码
class Solution {
    public static String minWindow(String s, String t) {
        int[] hash2 = new int[80];
        int[] hash1 = new int[80];
        int kinds = 0;
        for(char c : t.toCharArray()){
            if(hash1[c - 'A']++ == 0){
                kinds++;
            }
        }

        int minLen = s.length() + 1;
        int len = s.length();
        int begin = -1;
        for(int left = 0,right = 0,count = 0;right < s.length();right++){
            char in = s.charAt(right);
            hash2[in - 'A']++;
            if(hash2[in - 'A'] == hash1[in - 'A']){
                count++;
            }
            while(count == kinds && left <= right){
                int tmp = right - left + 1;
                if(tmp < minLen){
                    begin = left;
                    minLen = tmp;
                }
                char out = s.charAt(left);
                if(hash2[out - 'A'] == hash1[out - 'A']){
                    count--;
                }
                hash2[out - 'A']--;
                left++;
            }
        }
        return minLen == s.length()+1 ? "" : s.substring(begin,begin+minLen);
    }
}
相关推荐
sinat_286945194 分钟前
opencode
人工智能·算法·chatgpt
工口发动机20 分钟前
ABC440DEF简要题解
c++·算法
C++ 老炮儿的技术栈34 分钟前
什么是通信规约
开发语言·数据结构·c++·windows·算法·安全·链表
零小陈上(shouhou6668889)1 小时前
K-近邻算法 - lazy learning的代表
算法·近邻算法
有一个好名字1 小时前
力扣-从字符串中移除星号
java·算法·leetcode
萧瑟其中~1 小时前
二分算法模版——基础二分查找,左边界查找与右边界查找(Leetcode的二分查找、在排序数组中查找元素的第一个位置和最后一个位置)
数据结构·算法·leetcode
码上就好ovo1 小时前
Atcoder Beginnner Contest 440
算法
高洁011 小时前
CLIP 的双编码器架构是如何优化图文关联的?(3)
深度学习·算法·机器学习·transformer·知识图谱
jllllyuz1 小时前
MATLAB实现蜻蜓优化算法
开发语言·算法·matlab