30. 串联所有单词的子串

30. 串联所有单词的子串

题解:

  1. 题目可以转换为:把字符串s按word的长度划分为一堆集合后,然后这一堆集合中,找出完全由words集合组成的字符串。
  2. 滑动窗口,每次滑动按一个word的长度滑,当窗口内的元素完全等于words的元素时,此时的下标即为答案。
class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> res = new ArrayList<>();
        int wsl = words.length;
        if (wsl == 0) return res;
        int sl = s.length();
        int wl = words[0].length();
        // 集合1
        Map<String, Integer> map1 = new HashMap<>();
        for (String word : words) {
            Integer wordNum = map1.getOrDefault(word, 0);
            map1.put(word, wordNum + 1);
        }
        for (int i = 0; i < wl; i++) {
            // 集合2
            Map<String, Integer> map2 = new HashMap<>();
            // 此时集合2中拥有集合1中的元素个数
            int cnt = 0;
            for (int j = i; j + wl <= sl; j += wl) {
                // 超过words 能拼凑的最长字符串
                if (j >= i + wsl * wl) {
                    // 窗口右滑,把第一个单词剔除
                    int startIndex = j - wsl * wl;
                    String word = s.substring(startIndex, startIndex + wl);
                    Integer wordNum = map2.getOrDefault(word, 0);
                    map2.put(word, wordNum - 1);
                    // 剔除了合法的词
                    if (map2.getOrDefault(word, 0) < map1.getOrDefault(word, 0)) cnt--;
                }
                String word = s.substring(j, j + wl);
                Integer wordNum = map2.getOrDefault(word, 0);
                map2.put(word, wordNum + 1);
                if (map2.getOrDefault(word, 0) <= map1.getOrDefault(word, 0)) cnt++;
                // 两个集合相等
                if (cnt == wsl) res.add(j - (wsl - 1) * wl);
            }
        }
        return res;
    }
}
posted @   Eiffelzero  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
点击右上角即可分享
微信分享提示