Skip to content

Commit e7b016a

Browse files
authored
Update Substring with Concatenation of All Words.java
1 parent fd23e4c commit e7b016a

File tree

1 file changed

+43
-29
lines changed

1 file changed

+43
-29
lines changed
Lines changed: 43 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,53 @@
11
class Solution {
22
public List<Integer> findSubstring(String s, String[] words) {
3-
if (s.length() == 0 || words.length == 0) {
4-
return new ArrayList<>();
5-
}
6-
Map<String, Integer> wordFreqMap = new HashMap<>();
3+
int numberOfWords = words.length;
4+
int singleWordLength = words[0].length();
5+
int totalSubstringLength = singleWordLength * numberOfWords;
6+
Map<String, Integer> wordCount = new HashMap<>();
77
for (String word : words) {
8-
wordFreqMap.put(word, wordFreqMap.getOrDefault(word, 0) + 1);
8+
wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);
99
}
10-
int stringLength = s.length();
11-
int wordCount = words.length;
12-
int singleWordLength = words[0].length();
13-
List<Integer> indices = new ArrayList<>();
14-
for (int i = 0; i + singleWordLength * wordCount <= stringLength; i++) {
15-
if (match(s, i, singleWordLength, wordFreqMap, wordCount)) {
16-
indices.add(i);
17-
}
10+
List<Integer> result = new ArrayList<>();
11+
for (int i = 0; i < singleWordLength; i++) {
12+
slidingWindow(i, s, result, singleWordLength, totalSubstringLength, wordCount, numberOfWords);
1813
}
19-
return indices;
14+
return result;
2015
}
21-
22-
private boolean match(String s, int start, int singleWordLength, Map<String, Integer> wordFreqMap, int wordCount) {
23-
Map<String, Integer> currFreqMap = new HashMap<>();
24-
for (int i = 0; i < wordCount; i++) {
25-
String currWord = s.substring(start + i * singleWordLength, start + (i + 1) * singleWordLength);
26-
Integer freq = wordFreqMap.get(currWord);
27-
// Word not in required words
28-
if (freq == null) {
29-
return false;
30-
}
31-
currFreqMap.put(currWord, currFreqMap.getOrDefault(currWord, 0) + 1);
32-
// Word occurs more than the required count
33-
if (currFreqMap.get(currWord) > freq) {
34-
return false;
16+
17+
private void slidingWindow(int left, String s, List<Integer> answer, int singleWordLength,
18+
int totalSubstringLength, Map<String, Integer> wordCount, int numberOfWords) {
19+
Map<String, Integer> wordsFound = new HashMap<>();
20+
int wordsUsed = 0;
21+
boolean excessWord = false;
22+
int n = s.length();
23+
for (int right = left; right <= n - singleWordLength; right += singleWordLength) {
24+
String currSubstring = s.substring(right, right + singleWordLength);
25+
if (!wordCount.containsKey(currSubstring)) {
26+
wordsFound.clear();
27+
wordsUsed = 0;
28+
excessWord = false;
29+
left = right + singleWordLength;
30+
} else {
31+
while (right - left == totalSubstringLength || excessWord) {
32+
String leftmostWord = s.substring(left, left + singleWordLength);
33+
left += singleWordLength;
34+
wordsFound.put(leftmostWord, wordsFound.get(leftmostWord) - 1);
35+
if (wordsFound.get(leftmostWord) >= wordCount.get(leftmostWord)) {
36+
excessWord = false;
37+
} else {
38+
wordsUsed--;
39+
}
40+
}
41+
wordsFound.put(currSubstring, wordsFound.getOrDefault(currSubstring, 0) + 1);
42+
if (wordsFound.get(currSubstring) <= wordCount.get(currSubstring)) {
43+
wordsUsed++;
44+
} else {
45+
excessWord = true;
46+
}
47+
if (wordsUsed == numberOfWords && !excessWord) {
48+
answer.add(left);
49+
}
3550
}
3651
}
37-
return true;
3852
}
3953
}

0 commit comments

Comments
 (0)