Valid Anagram
Given two strings sttruetsfalse
Note: 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.
Example 1
Output: true
Explanation: "nagaram" is an anagram of "anagram" word, we can form the word "nagaram" by re-arranging leters from "anagram" only once.
Example 2
Output: true
Explanation: "car" cannot be formed by re-arranging leters from "rat".
Constraints:
1 <= s.length, t.length <= 5 * 104 ands consist of lowercase English letters.t
Follow up: What if the inputs contain Unicode characters? How would you adapt your solution to such a case?
Contents
Solution 1 - Using an array to store count of each character appearance
In this approach, we will use a temporary array to store each character count from input string st
-
We will create a function
that takes input arguments stringusingArray ands .t -
Base case is, if input strings
ands lengths are not same, then we can simply returnt because these strings won't be anagrams of each other.false -
Create a temporary array with size as
if the characters going to be lowercase or uppercase english alphabet letters. (If the characters are going to be ASCII characters, then you can initialize array with26 size)128 -
Then, for each character in input string
add character count in correponding position.t -
Then, for each character in input string
, decrement the count from temporary array that we have created above.s-
If the count at character position becomes
, this means that the string is not an anagram.-1 -
If the count at character position never becomes
, then both strings are anagrams of each other.-1
-
If the count at character position becomes
int[] arr = new int[26];
for(int i=0; i<s.length(); i++) {
arr[s.charAt(i) - 'a']++;
}
public class ValidAnagram {
/* Using a temporary array */
static boolean usingArray(String s, String t) {
if(s.length() != t.length()) {
return false;
}
int[] arr = new int[26];
for(int i=0; i<s.length(); i++) {
arr[s.charAt(i) - 'a']++;
}
for(int j=0; j<t.length(); j++) {
int charIndex = t.charAt(j) - 'a';
arr[charIndex] = arr[charIndex] - 1;
if(arr[charIndex] == -1) {
return false;
}
}
return true;
}
}
Complexity Analysis:
Time complexity: Above code runs in O(n) time where n
Space complexity: O(1) since we are creating a temporary array with size 26 or 128 depends on characters type.
Solution 2 - Using two HashMaps to store count of each character appearance
In this approach, we will use a HashMapst
Note: This approach will work for any type of characters, ASCII or Unicode etc.
import java.util.HashMap;
import java.util.Map.Entry;
public class ValidAnagram {
/* Using two hashmaps two keep character count of each string s and t */
static boolean usingTwoHashMap(String s, String t) {
if(s.length() != t.length()) { // if the lengths are not same, they can't be anagrams
return false;
}
HashMap<Character, Integer> s_count = new HashMap<>();
HashMap<Character, Integer> t_count = new HashMap<>();
for(int i=0; i<s.length(); i++) {
s_count.merge(s.charAt(i), 1, Integer::sum);
t_count.merge(t.charAt(i), 1, Integer::sum);
}
//now, for every character count in s_count, check if the count in t_count matches or not
for(Entry<Character, Integer> charToCountEntry : s_count.entrySet()) {
if(!charToCountEntry.getValue().equals(t_count.get(charToCountEntry.getKey()))) {
return false;
}
}
return true;
}
}
Complexity Analysis:
Time complexity: Above code runs in O(n) time where n
Space complexity: O(n) since we are storing character count into a HashMap
Solution 3 - Using one HashMap to store count of each character appearance (Solution to follow-up question)
This approach is same as solution 1, instead of using an array we will be using a HashMap, so that the solution will work for any type of characters that are in input strings like ASCII or Unicode etc.
import java.util.HashMap;
public class ValidAnagram {
/* Using a single HashMap - equivalent to using arrays approach*/
static boolean usingSingleHashMap(String s, String t) {
if(s.length() != t.length()) {
return false;
}
HashMap<Character, Integer> s_count = new HashMap<>();
for(int i=0; i<s.length(); i++) {
s_count.merge(s.charAt(i), 1, Integer::sum);
}
for(int j=0; j<t.length(); j++) {
int newValAfter = s_count.merge(t.charAt(j), -1, Integer::sum); // this returns the new value after decrementing the count
if(newValAfter == -1) {
return false;
}
}
return true;
}
}
Complexity Analysis:
Time complexity: Above code runs in O(n) time where n
Space complexity: O(n) since we are storing character count into a HashMap
Above implementations source code can be found at