DEV Community

Wenqi Jiang
Wenqi Jiang

Posted on

30. Substring with Concatenation of All Words

Description

You are given a string s and an array of strings words of the same length. Return all starting indices of substring(s) in s that is a concatenation of each word in words exactly oncein any order, and without any intervening characters.

You can return the answer in any order.

Example 1:

Input: s = "barfoothefoobarman", words = ["foo","bar"]
Output: [0,9]
Explanation: Substrings starting at index 0 and 9 are "barfoo" and "foobar" respectively.
The output order does not matter, returning [9,0] is fine too.
Enter fullscreen mode Exit fullscreen mode

Example 2:

Input: s = "wordgoodgoodgoodbestword", words = ["word","good","best","word"]
Output: []
Enter fullscreen mode Exit fullscreen mode

Example 3:

Input: s = "barfoofoobarthefoobarman", words = ["bar","foo","the"]
Output: [6,9,12]
Enter fullscreen mode Exit fullscreen mode

Constraints:

  • 1 <= s.length <= 104
  • s consists of lower-case English letters.
  • 1 <= words.length <= 5000
  • 1 <= words[i].length <= 30
  • words[i] consists of lower-case English letters.

解题

方法一

思路

两个滑动窗口

代码

public List<Integer> findSubstring(String s, String[] words) {
    ArrayList<Integer> res = new ArrayList<>();
    HashMap<String, Integer> map = new HashMap<>();
    int one_word = words[0].length();
    int word_num = words.length;
    int all_len = one_word * word_num;
    for (String word : words) {
        map.put(word, map.getOrDefault(word, 0) + 1);
    }

    for (int i = 0; i < s.length() - all_len + 1; i++) {
        HashMap<String, Integer> tmp_map = new HashMap<>();
        for (int j = 0; j < all_len; j += one_word) {
            String w = s.substring(i + j, i + j + one_word);
            if (!map.containsKey(w)) {
                break;
            }
            tmp_map.put(w, tmp_map.getOrDefault(w, 0) + 1);
        }
        if (map.equals(tmp_map))
            res.add(i);
    }
    return res;
}
Enter fullscreen mode Exit fullscreen mode

复杂度分析

  • 时间复杂度: O(nm)
  • 空间复杂度: O(m)

方法二

思路

代码

class Solution {
public:
    vector<int> findSubstring(string s, vector<string>& words) {
        vector<int> res;
        if (words.empty()) return res;
        int m = words.size(), w = words[0].size(), mw = m * w, cnt = 0;
        unordered_map<string, int> wf, wd;
        for (auto& word : words) wf[word]++;
        for (int i = 0; i < w; i++) {
            for (int j = i; j + w <= s.size(); j += w) {
                if (j >= i + mw) {
                    string word = s.substr(j - mw, w);
                    wd[word]--;
                    if (wd[word] < wf[word]) cnt--;
                }
                string word = s.substr(j, w);
                wd[word]++;
                if (wd[word] <= wf[word]) cnt++;
                if (cnt == m) res.push_back(j - (m - 1) * w);
            }
            wd.clear();
            cnt = 0;
        }

        return res;
    }
};
Enter fullscreen mode Exit fullscreen mode

复杂度分析

  • 时间复杂度: O(n*w)
  • 空间复杂度: O(n)

Top comments (0)