首页 > 其他分享 >30. 串联所有单词的子串

30. 串联所有单词的子串

时间:2022-11-06 01:11:22浏览次数:76  
标签:子串 map2 wl word int 30 单词 words wordNum

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;
    }
}

标签:子串,map2,wl,word,int,30,单词,words,wordNum
From: https://www.cnblogs.com/eiffelzero/p/16861809.html

相关文章