Given two strings s and t , write a function to determine if t is an anagram of s.
Example 1:
Input: s = “anagram”, t = “nagaram” Output: true
Example 2:
Input: s = “rat”, t = “car” Output: false
var isAnagram = function(s, t) {
let s1=s.split('');
let s2=t.split('');
//sort arrays
s1=s1.sort();
s2=s2.sort();
console.log(s1);
console.log(s2);
//compare arrays
for (let i=0;i<s1.length;i++) {
if (s1[i]!=s2[i]) {
return false;
}
}
//if different lengths
if (s1.length!=s2.length) {
return false;
}
return true;
};
Approaches
An anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
Two strings are an anagram if they have the same characters.
Eg: "anagram" and "nagaram" are anagrams because then you can rearrange anagram into nagaram
Eg: "rat" and "cat" cannot be rearranged in the card because you don't have a C
If the strings are the same length then they might be an anagram or might not be but if it’s not the same length it cannot be an anagram because you’ll have characters left over from the longer string.
If we use a sort and compare method it’ll be O(n*logn). O(n*logn) for the sort, and O(n) for the compare, which ends up being O(n*logn).
We could count the number of characters and create a counter object that counts the number of each character. If the character counts between the two strings are the same, then if we have an anagram.
Why would we want to use these counts instead of the sorted string? What if you have a very long string and you want to compare more than one string? For example if you have a 2,000 character string you don’t want to check two thousand characters every time to every other string you just want to check up to 26 or 52 character blocks. In this case we’re only comparing two strings and only doing it once so here we just skip that but it’s something to keep in mind as well.
Code Breakdown
Let’s go over the solution block by block and explain as we go.
let s1=s.split('');
let s2=t.split('');
//sort arrays
s1=s1.sort();
s2=s2.sort();
What that split function does is separate every character into a separate element of the array.
For the sort function, if we don’t specify a callback it’ll do a default sort with alphabetically/numerically. It can have some weird behavior if you’re sorting a number that’s a string for example but in this case it’s fairly straightforward. If it’s a more complicated sort you just want to be careful that you pass your custom call back to the sort function or be very familiar with the default behaviors.
//compare arrays
for (let i=0;i<s1.length;i++) {
if (s1[i]!=s2[i]) {
return false;
}
}
Here we compare the arrays. If every element of the first array is equal to the second array same element then great but if at any point it’s not then it’s not an anagram.
//if different lengths
if (s1.length!=s2.length) {
return false;
}
This part is fairly important. The iterative loop above only checks the elements that are in the first array. If the first array is longer or same length as second array, then it’ll work. It’ll work in that it’ll return false because if the second array is shorter, there will be at least one element where it doesn’t match. However, if the second array contains additional elements not in the first array, it won’t return false but it’s not an anagram. So here we check the lengths to make sure the above iterative check works, returning false if otherwise.
Now if we haven’t returned false yet, we return true since what remains is an anagram 🙂
Time Complexity
The time complexity is O(n*logn), and this is because of the sort.