Answer
Check if Two Strings are Anagrams
Anagram: Two strings that contain the same characters in the same frequency. "listen" and "silent" → Anagrams "hello" and "world" → Not Anagrams
Method 1: Sort and Compare (Simplest)
Java
public static boolean isAnagram(String str1, String str2) {
if (str1 == null || str2 == null) return false;
if (str1.length() != str2.length()) return false;
char[] arr1 = str1.toLowerCase().toCharArray();
char[] arr2 = str2.toLowerCase().toCharArray();
Arrays.sort(arr1);
Arrays.sort(arr2);
return Arrays.equals(arr1, arr2);
}
System.out.println(isAnagram("listen", "silent")); // true
System.out.println(isAnagram("triangle", "integral")); // true
System.out.println(isAnagram("hello", "world")); // false
Method 2: Character Frequency Array (Optimal O(n))
Java
public static boolean isAnagramFrequency(String str1, String str2) {
if (str1.length() != str2.length()) return false;
int[] count = new int[26]; // for lowercase a-z
for (char c : str1.toLowerCase().toCharArray()) {
count[c - 'a']++; // increment for str1
}
for (char c : str2.toLowerCase().toCharArray()) {
count[c - 'a']--; // decrement for str2
}
// If anagram — all counts should be 0
for (int c : count) {
if (c != 0) return false;
}
return true;
}
Method 3: HashMap (Handles Unicode/spaces)
Java
public static boolean isAnagramMap(String str1, String str2) {
str1 = str1.toLowerCase().replaceAll("\\s", "");
str2 = str2.toLowerCase().replaceAll("\\s", "");
if (str1.length() != str2.length()) return false;
Map<Character, Integer> freq = new HashMap<>();
for (char c : str1.toCharArray()) {
freq.put(c, freq.getOrDefault(c, 0) + 1);
}
for (char c : str2.toCharArray()) {
if (!freq.containsKey(c)) return false;
freq.put(c, freq.get(c) - 1);
if (freq.get(c) == 0) freq.remove(c);
}
return freq.isEmpty();
}
Method 4: Java 8 Streams
Java
public static boolean isAnagramStream(String str1, String str2) {
if (str1.length() != str2.length()) return false;
Map<Integer, Long> freq1 = str1.toLowerCase().chars()
.boxed()
.collect(Collectors.groupingBy(c -> c, Collectors.counting()));
Map<Integer, Long> freq2 = str2.toLowerCase().chars()
.boxed()
.collect(Collectors.groupingBy(c -> c, Collectors.counting()));
return freq1.equals(freq2);
}
Test Cases
Java
@Test
public void testAnagram() {
// Anagrams
assertTrue(isAnagram("listen", "silent"));
assertTrue(isAnagram("triangle", "integral"));
assertTrue(isAnagram("Astronomer", "Moon starer")); // with spaces
assertTrue(isAnagram("abc", "bca"));
assertTrue(isAnagram("DEBIT CARD", "BAD CREDIT"));
// Not anagrams
assertFalse(isAnagram("hello", "world"));
assertFalse(isAnagram("rat", "car"));
// Edge cases
assertFalse(isAnagram("abc", "ab")); // different lengths
assertFalse(isAnagram(null, "abc"));
assertTrue(isAnagram("", ""));
}
