Skip to content

Commit e93a1ee

Browse files
committed
Find all anagrams in a string
1 parent 4684f49 commit e93a1ee

File tree

1 file changed

+27
-25
lines changed

1 file changed

+27
-25
lines changed

0438_findAllAnagramsInAString.js

+27-25
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,39 @@
11
/**
2-
* @param {string} s
3-
* @param {string} p
4-
* @return {number[]}
2+
* @param {string} stream Input string.
3+
* @param {string} word Word to compare substring to.
4+
* @return {number[]} Array with indexes of all substrings that are anagrams of word.
5+
* @summary Find All Anagrams in a String {@link https://leetcode.com/problems/find-all-anagrams-in-a-string/}
6+
* @description Given two input strings return indexes of substrings that are anagrams of second input.
7+
* Space O(A+B) - A length of string 'word', B length of string 'stream'.
8+
* Time O(1) - Two new arrays, each of 26 elements.
59
*/
10+
const findAnagrams = (stream, word) => {
11+
const counts = Array(26);
12+
const currentCount = Array(26);
13+
const offset = 'a'.charCodeAt();
14+
const answer = [];
15+
const sLength = stream.length;
16+
const wLength = word.length;
617

7-
const isAnagram = (word, candidate) => {
8-
if (word.length !== candidate.length) return false;
18+
for (let i = 0; i < wLength; i++) {
19+
const index = word[i].charCodeAt() - offset;
920

10-
const charMap = {};
11-
for (let index = 0; index < word.length; index++) {
12-
if (word.indexOf(candidate[index]) < 0) {
13-
return false;
14-
}
15-
charMap[word[index]] = charMap[word[index]] ? charMap[word[index]] + 1 : 1;
16-
charMap[candidate[index]] = charMap[candidate[index]] ? charMap[candidate[index]] - 1 : -1;
21+
counts[index] = counts[index] ? counts[index] + 1 : 1;
1722
}
1823

19-
return Object.keys(charMap).every(char => charMap[char] === 0);
20-
};
21-
22-
const findAnagrams = (s, p) => {
23-
const anagrams = {};
24-
anagrams[p] = true;
24+
for (let i = 0; i < sLength; i++) {
25+
const index = stream[i].charCodeAt() - offset;
2526

26-
const answer = [];
27-
28-
const length = s.length - p.length + 1;
29-
for (let index = 0; index < length; index++) {
30-
const candidate = s.slice(index, index + p.length);
27+
currentCount[index] = currentCount[index] ? currentCount[index] + 1 : 1;
3128

32-
if (anagrams[candidate] === undefined) anagrams[candidate] = isAnagram(p, candidate);
29+
if (i >= wLength) {
30+
const index = stream[i - wLength].charCodeAt() - offset;
31+
currentCount[index] = currentCount[index] ? currentCount[index] - 1 : undefined;
32+
}
3333

34-
if (anagrams[candidate]) answer.push(index);
34+
if (counts.every((count, index) => count === currentCount[index])) {
35+
answer.push(i - wLength + 1);
36+
}
3537
}
3638

3739
return answer;

0 commit comments

Comments
 (0)