30. Substring with Concatenation of All Words 🌐
Difficulty: Hard - Tags: String, Hash Table, Sliding Window
Problem Statement 📜
You are given a string s and an array of strings words. All the strings of words are of the same length.
A concatenated string is a string that exactly contains all the strings of any permutation of words concatenated.
Return an array of the starting indices of all the concatenated substrings in s. You can return the answer in any order.
Examples 🌟
🔹 Example 1:
Input:
s = "barfoothefoobarman"
words = ["foo","bar"]Output:
[0,9]Explanation:
The substring starting at 0 is "barfoo". It is the concatenation of
["bar","foo"]which is a permutation ofwords.The substring starting at 9 is "foobar". It is the concatenation of
["foo","bar"]which is a permutation ofwords.
🔹 Example 2:
Input:
s = "wordgoodgoodgoodbestword"
words = ["word","good","best","word"]Output:
[]Explanation: There is no concatenated substring.
🔹 Example 3:
Input:
s = "barfoofoobarthefoobarman"
words = ["bar","foo","the"]Output:
[6,9,12]Explanation:
The substring starting at 6 is "foobarthe". It is the concatenation of
["foo","bar","the"].The substring starting at 9 is "barthefoo". It is the concatenation of
["bar","the","foo"].The substring starting at 12 is "thefoobar". It is the concatenation of
["the","foo","bar"].
Constraints ⚙️
1 <= s.length <= 10^41 <= words.length <= 50001 <= words[i].length <= 30sandwords[i]consist of lowercase English letters.
Solution 💡
To solve this problem, we can use a Sliding Window approach with a Hash Table to keep track of the count of each word in words.
Calculate Word Lengths:
Since all words in
wordsare the same length, we can calculate the total length of concatenated words and use it to limit our sliding window.
Create a Dictionary for Words:
Create a
wordCountdictionary to count occurrences of each word inwords.
Slide Over Substrings:
Use a sliding window approach across
s, iterating for each possible starting position to cover all possible concatenations.For each substring in the current window, check if it matches the count in
wordCount.
Verify and Store Results:
If the substring contains all words with matching frequencies, store the starting index.
Java Solution
import java.util.*;
class Solution {
public List<Integer> findSubstring(String s, String[] words) {
// Map to store the frequency of each word in `words`
Map<String, Integer> wordCount = new HashMap<>();
for (String word : words) {
wordCount.merge(word, 1, Integer::sum);
}
int strLength = s.length();
int wordsCount = words.length;
int wordLength = words[0].length();
List<Integer> indices = new ArrayList<>();
// Iterate over possible start indices within a word length
for (int i = 0; i < wordLength; i++) {
Map<String, Integer> currentCount = new HashMap<>();
int left = i, right = i;
int totalWords = 0;
// Slide the window through the string
while (right + wordLength <= strLength) {
// Extract the current word from the string
String sub = s.substring(right, right + wordLength);
right += wordLength;
// If the word is not in `wordCount`, reset the window
if (!wordCount.containsKey(sub)) {
currentCount.clear();
left = right;
totalWords = 0;
continue;
}
// Increment the count of the current word in `currentCount`
currentCount.merge(sub, 1, Integer::sum);
++totalWords;
// If a word's count exceeds the allowed frequency, shrink the window
while (currentCount.get(sub) > wordCount.get(sub)) {
String removed = s.substring(left, left + wordLength);
left += wordLength;
currentCount.merge(removed, -1, Integer::sum);
--totalWords;
}
// If the window contains all words exactly once, record the starting index
if (totalWords == wordsCount) {
indices.add(left);
}
}
}
return indices; // Return the list of starting indices
}
}
Time Complexity ⏳
O(N * M): Where
Nis the length ofsandMis the total length of the words inwords. We check each possible substring of lengthtotalLengthins.
Space Complexity 💾
O(W): Where
Wis the number of unique words inwords, for storing them inwordCountandseenWordshash maps.
You can find the full solution here and another solution here but it Time Limit Exceeded 😢.
Last updated
Was this helpful?