This was another challenge that I received recently as a whiteboarding problem in a real life interview. I didn't find a whole solution, there were many edge cases I did not account for. If you missed my blog post about the other question given to me, you can read that HERE
Real whiteboarding challenge
This was the task given to me:
Create a function that takes in 2 strings and outputs whether the two strings are anagrams.
Thought process
My first solution, which wasn't a complete solution, only worked for certain cases. It went something like this:
function isAnagram2(str1, str2) {
//we loop over str1
for (let i = 0; i < str1.length; i++) {
//'see does str2 include letter at str[i]'
if (str2.includes(str1[i])) {
//'keep looping while true'
continue;
} else return false;
}
//'made it through str1 letters return true'
return true;
}
The issue with this solution comes when you compare two strings that have all the same letters, but have duplicates of those letters contained within one of the arguments. For instance, if we used the above function and compared "dog" to "ddoogg." We can clearly see that these words are not anagrams. They do have all the same letters, so it would return a false positive. When this case was brought up to me, my pivot solution was to add a conditional if statement to check the lengths match as well. This would also a false positive in a case of comparing "dogg" to "doog." The interviewers had been reading this blog and then told me that in a recent blog I used something that might work. So, I started doing something like this, but with more loops. Also, an issue would arise when comparing the two objects created:
function isAnagram(string1, string2) {
let words = [];
for (let i = 0, j = arguments.length; i < j; i++) {
let word = {};
for (let k = 0; k < arguments[i].length; k++) {
let key = arguments[i][k];
if (word[key]) {
word[key]++;
} else {
word[key] = 1;
}
}
words.push(word);
}
return words[0] == words[1];
};
The REAL solution
Afterwards, I sat down and really thought my process out. How could I compare these two arguments to see if they were anagrams? After about 20 minutes, I pivoted again from my previous approaches. What if I sorted the words alphabetically and then compared them. This would mean that any anagrams would have the same value!
Here's that solution:
function anagram(str1, str2) {
//container variable
let comparedContainer = [];
//loop over each argument
for (let i = 0; i < arguments.length; i++) {
//store each word split, sorted alphabetically, and joined back together
comparedContainer[i] = arguments[i].split('').sort().join('');
}
//now compare equality
return comparedContainer[0] == comparedContainer[1];
}
After I came up with this solution & did my little happy dance, I refactored to:
function isAnagram2(str1, str2) {
return str1.split('').sort().join('') == str2.split('').sort().join('')
}
Note
I have started a hackathon with some friends for the next few posts I will stray from the challenge blogs to present: DigitalOcean and MongoDB hackathon. This will blog about our process and peer into the application we've decided to make.