leetcode30--滑动窗口系列

class Solution {
    //我们使用滑动窗口来解决这个字符串匹配问题
    public static List<Integer> findSubstring(String s, String[] words) {

        //使用res来接收最后结果
        ArrayList<Integer> res = new ArrayList<>();

        //1. 统计words数组中每个单词出现的次数,使用map来进行存储
        HashMap<String, Integer> wordMap = new HashMap<>();
        for (String str : words) {
            if (wordMap.containsKey(str)) {
                wordMap.put(str, wordMap.get(str) + 1);
            } else {
                //如果map中不存在,则直接加入
                wordMap.put(str, 1);
            }
        }

        //2. 找出窗口的大小
        int wordLen = words[0].length();
        //因为每个单词的长度是相等的故,不管他有没有重复,我们直接使用每个单词的长度*单词的数量
        //得到窗口的大小
        int len = wordLen * words.length;

        //3. 开始匹配,这里要注意我们的循环长度,因为我们已经是从一个窗口开始匹配,那么他循环的次数等于当前
        //主串的总长-窗口长+1次
        for (int i = 0; i < s.length() - len + 1; i++) {
            //开始取窗口大小的子串
            String s1 = s.substring(i, i + len);
            //新建一个map用来统计当前s1中串中每个单词大小的串的出现次数,如果出现的次数等于前面统计的
            //wordMap中统计的次数,那门他们绝逼相等
            //下面使用另一种,就是我们把前面拿到的hashmap放入到这个临时的map中,此时tmpmap中记录了
            //words中每个单词出现的次数,我们只需要遍历当前串,将遍历到的单词在临时map中将其次数减少即可,最后,
            //我们判断临时map是否为空,如果为空,则表示完全匹配
            HashMap<String, Integer> tmpMap = new HashMap<>(wordMap);
            //遍历这个取出的子串,这里我们规定遍历每次走一个单词长度
            for (int j = 0; j < s1.length(); j += wordLen) {
                String word = s1.substring(j, j + wordLen);
                if (tmpMap.containsKey(word)) {
                    tmpMap.put(word, tmpMap.get(word) - 1);
                    if (tmpMap.get(word) == 0) {
                        //移除当前哈希表中的元素,这里要进行移除,当我们map减少至0时,此时map中还是存在这个word的,话句话说就是他还会去继续匹配
                        //那么,他就永远不会有与子串匹配的,故要移除。
                        tmpMap.remove(word);
                    }
                } else {
                    //不包含的话肯定不匹配,直接跳出循环即可
                    break;
                }
            }
            //内层循环结束
            if (tmpMap.size() == 0) {
                //完全匹配
                res.add(i);
            }
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无敌小胖子.com

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值