Loading

LeetCode 30 串联所有单词的字串

LeetCode30 串联所有单词的字串

题目描述

给定一个字符串 s 和一些长度相同的单词 words。找出 s 中恰好可以由 words 中所有单词串联形成的子串的起始位置

注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。

注意:单词的长度相同

样例

输入:
  s = "barfoothefoobarman",
  words = ["foo","bar"]
输出:[0,9]
解释:
从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。
输出的顺序不重要, [9,0] 也是有效答案。
输入:
  s = "wordgoodgoodgoodbestword",
  words = ["word","good","best","word"]
输出:[]

算法分析

思路来源:小呆呆

  • find哈希表表示当从i开始长度是n * len的滑动窗口中将该窗口的字符串以长度是len进行分割出来记录元素的哈希表,记录该窗口每个单词有多少个
  • 枚举窗口内的每一个单词
  • 加入find或者不加入

时间复杂度\(O(s.length()\*n*len)\)

Java代码

class Solution {
    public List<Integer> findSubstring(String s, String[] words) {
        List<Integer> ans = new ArrayList<Integer>();
        if(words.length == 0) return ans;

        HashMap<String, Integer> map = new HashMap<String, Integer>();
        for(String word : words){
            map.put(word, map.getOrDefault(word, 0) + 1);
        }

        int n = words.length;
        int len = words[0].length();

        HashMap<String, Integer> find = new HashMap<String, Integer>();

        for(int i = 0; i <= s.length() - n * len; i++){
            find.clear();
            int j = 0;
            for(;j < n;j++){
                String t = s.substring(i + j * len, i + j * len + len);
                if(map.containsKey(t)){
                    find.put(t, find.getOrDefault(t, 0) + 1);
                    if(find.get(t) > map.get(t)) break;
                }
                else break;
            }

            if(j == n) ans.add(i);
        }

        return ans;

    }
}
posted @ 2020-10-31 17:49  想用包子换论文  阅读(134)  评论(0)    收藏  举报