xxxxxxxxxx
class Solution {
private HashMap<String, Integer> wordCount = new HashMap<String, Integer>();
private int n;
private int wordLength;
private int substringSize;
private int k;
private void slidingWindow(int left, String s, List<Integer> answer) {
HashMap<String, Integer> wordsFound = new HashMap<>();
int wordsUsed = 0;
boolean excessWord = false;
// Do the same iteration pattern as the previous approach - iterate
// word_length at a time, and at each iteration we focus on one word
for (int right = left; right <= n - wordLength; right += wordLength) {
String sub = s.substring(right, right + wordLength);
if (!wordCount.containsKey(sub)) {
// Mismatched word - reset the window
wordsFound.clear();
wordsUsed = 0;
excessWord = false;
left = right + wordLength;
} else {
// If we reached max window size or have an excess word
while (right - left == substringSize || excessWord) {
String leftmostWord = s.substring(left, left + wordLength);
left += wordLength;
wordsFound.put(leftmostWord, wordsFound.get(leftmostWord) - 1);
if (wordsFound.get(leftmostWord) >= wordCount.get(leftmostWord)) {
// This word was an excess word
excessWord = false;
} else {
// Otherwise we actually needed it
wordsUsed--;
}
}
// Keep track of how many times this word occurs in the window
wordsFound.put(sub, wordsFound.getOrDefault(sub, 0) + 1);
if (wordsFound.get(sub) <= wordCount.get(sub)) {
wordsUsed++;
} else {
// Found too many instances already
excessWord = true;
}
if (wordsUsed == k && !excessWord) {
// Found a valid substring
answer.add(left);
}
}
}
}
public List<Integer> findSubstring(String s, String[] words) {
n = s.length();
k = words.length;
wordLength = words[0].length();
substringSize = wordLength * k;
for (String word : words) {
wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);
}
List<Integer> answer = new ArrayList<>();
for (int i = 0; i < wordLength; i++) {
slidingWindow(i, s, answer);
}
return answer;
}
}
xxxxxxxxxx
class Solution {
public:
vector<int> findSubstring(string s, vector<string>& words) {
}
};
xxxxxxxxxx
class Solution {
public List<Integer> findSubstring(String s, String[] words) {
}
}
xxxxxxxxxx
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* findSubstring(char * s, char ** words, int wordsSize, int* returnSize){
}
xxxxxxxxxx
public class Solution {
public IList<int> FindSubstring(string s, string[] words) {
}
}
xxxxxxxxxx
/**
* @param {string} s
* @param {string[]} words
* @return {number[]}
*/
var findSubstring = function(s, words) {
};
xxxxxxxxxx
# @param {String} s
# @param {String[]} words
# @return {Integer[]}
def find_substring(s, words)
end
xxxxxxxxxx
class Solution {
func findSubstring(_ s: String, _ words: [String]) -> [Int] {
}
}
xxxxxxxxxx
class Solution {
/**
* @param String $s
* @param String[] $words
* @return Integer[]
*/
function findSubstring($s, $words) {
}
}