I am trying to solve a Hackerrank problem Sherlock and Anagrams. I think my code is valid but somehow times out for some of the test cases. Any tips on how to improve its performance? Critique unrelated to performance is welcome as well!
Here is my main method which gets a string as an input and returns an integer that represents the number of pairs of substrings of the string that are anagrams of each other:
function sherlockAndAnagrams(s) {
let substrings = [];
let pairs = [];
// get all substrings
for (let i = 0; i < s.length+1; i++) {
for (let j = i+1; j < s.length+1; j++) {
substrings.push(s.substring(i, j));
}
}
// sort substrings so they can be compared using ===
substrings = substrings.map(sub => [...sub].sort().join(""));
// count them by comparing each with each skipping the ones with different length
return substrings.reduce((counter, sub, index, arr) => {
return counter += arr.reduce((acc, item, jndex) => {
if (sub.length === item.length && sub === item && index !== jndex) {
let uid = [index, jndex].sort().join("");
if (!pairs.includes(uid)) {
acc++;
pairs.push(uid);
}
}
return acc;
}, 0);
}, 0);
}
Here is a shortened version of the problem description as additional context:
Two strings are anagrams of each other if the letters of one string can be rearranged to form the other string. Given a string, find the number of pairs of substrings of the string that are anagrams of each other.
sherlockAndAnagrams has the following parameter: s: a string
It must return an integer that represents the number of anagrammatic pairs of substrings in s. For each query, return the number of unordered anagrammatic pairs.