LeetCode刷题滑动窗口(串联所有单词的子串+最小覆盖的子串)Java

一,串联所有单词的子串

题目解析:

我们将s中的一整个字符串根据words中的每一个字符串的个数分为几个部分,就拿例题一来解释,我们将s中三个三个为一组,最终也就是要找到words中的所有的异位词,跟我上一个讲解的寻找所有的异位词的思想是一样的,但是这个题目在那个的基础上是需要注意几个点的,就是我们right移动的步长是words上每一个数组的长度,然后我们也不能简单的就从头开始一个一个的分,还需要从第二个字符开始分,等等,这个也是看你words中的长度的

代码演示:

java 复制代码
    public static List<Integer> findSubstring(String s, String[] words) {
        //s = "barfoothefoobarman", words = ["foo","bar"]
        List<Integer> ret=new ArrayList<>();
        Map<String,Integer>hash1=new HashMap<>();
        //先统计words中的每一个字符串的长度以及有几个字符串
        int len=words[0].length();//以例题中举例就是3
        int wordsNum= words.length;//以例题中举例就是2
        //将words中的元素丢进hash1中
        for (String s1:words){
            hash1.put(s1,hash1.getOrDefault(s1,0)+1);//现在就是foo,1  bar,1
        }
        for (int i = 0; i < len; i++) {
            Map<String,Integer>hash2=new HashMap<>();
            for (int left = i,right=i,count=0; right+len <=s.length(); right+=len) {
                //进窗口
                String in=s.substring(right,right+len);
                hash2.put(in,hash2.getOrDefault(in,0)+1);
                //依旧是hash表中可以有多个相同的元素,可以出现foo,2这样的情况,但是count中始终是有效的才能加进去
                if (hash2.get(in)<=hash1.getOrDefault(in,0)){
                    count++;
                }
                //判断
                if (right-left+1>len*wordsNum){
                    //出窗口+维护count
                    String out=s.substring(left,left+len);
                    //这个时候我们的窗口已经大于应该有的数值了,并且此时我们的out这个字符串还不符合我们的有效值的时候
                    if (hash2.get(out)<=hash1.getOrDefault(out,0)){
                        count--;
                    }
                    //上面说的就是这个情况,我们需要出掉left的值
                    hash2.put(out,hash2.get(out)-1);
                    left+=len;
                }
                //经过上面的判断以及维护以及出掉无效left的值之后,还是满足有效值是我们需要的时候,这个时候就是正确的下标了
                if (count==wordsNum){
                    ret.add(left);
                }
            }
        }
        return ret;
    }

二,最小覆盖的子串

题目解析:

第一步还是将目标字符串通过遍历的形式加进一个哈希表1中,并且定义一个count变量来记录有效的数值(有效的字母的种类),接下来依旧是进窗口,维护count,判断,然后出窗口以及修改count,最后就是在合适的地方更新结果,这一套下来跟上面以及之前讲过的滑动窗口还是类似的,当然,这里都是字母,我们依然可以使用数组来模拟哈希表,让我们的时间更快

代码演示:

java 复制代码
class Solution {
public static String minWindow(String s, String t) {
        char[]ss=s.toCharArray();
        char[]tt=t.toCharArray();
        int[]hash1=new int[128];
        int kinds=0;
        for (char ch:tt){
            if (hash1[ch]==0){
                kinds++;
            }
            hash1[ch]++;
        }
        int[]hash2=new int[128];
        int minlen=Integer.MAX_VALUE;
        int begin=-1;
        for (int left = 0,right=0,count=0; right <ss.length; right++) {
            //进窗口+维护count
            char in=ss[right];
            hash2[in]++;
            if (hash2[in]==hash1[in]){
                count++;
            }
            //判断
            while (kinds==count){
                char out=ss[left];
                //更新结果+出窗口
                if (right-left+1<minlen){
                    minlen=right-left+1;
                    begin=left;
                }
                if (hash2[out]==hash1[out]){
                    count--;
                }
                hash2[out]--;
                left++;
            }
        }
        if (begin==-1){
            return new String();
        }else {
            return s.substring(begin,begin+minlen);
        }
    }
}
相关推荐
小雉系统5 小时前
BcoreOS安全通信架构:FsSession 抗算法后门安全设计
算法·安全·架构
唐墨12310 小时前
linux kernel 比较数据大小的宏定义
linux·算法
拂拉氏10 小时前
【知识讲解-题目讲解】 统计满足K约束的子字符串数量2 (滑动窗口+前缀和+二分查找+分析)
算法·前缀和·二分查找·滑动窗口
lsc_blog13 小时前
听到优化风声,先准备能由自己掌控的事
数据库·分布式·中间件·职场和发展·重构
通信小呆呆15 小时前
电子战抗干扰技术:当“不被干扰”成为一种系统
算法·通信·mimo·isac
笑容掩饰我的失落15 小时前
区块链从小白到精通(八):从零实现一个标准 ERC-20 代币(完整可运行代码)
算法·区块链·php·智能合约·哈希算法
Severus_black15 小时前
【C++初阶】Stack、Queue算法题大练兵!
c语言·c++·算法·stl
2601_9679791218 小时前
机器学习必修课:经典算法与Python实战
python·算法·机器学习·实战·课程
程序猿打工仔18 小时前
计算机基础(C语言)考编、专技岗
c语言·开发语言·算法