leetcode-150

Valid Anagram

Anagram problems are frequently asked in coding interviews. A common challenge is determining whether two strings are anagrams of each other. This problem tests your ability to efficiently manipulate and compare strings.

In this article, we will break down the problem, explain the approach, walk through the JavaScript solution, and provide some notes to enhance your understanding.


πŸ” Problem Statement

Two strings s and t are anagrams if the characters in s can be rearranged to form t. In other words, both strings must contain exactly the same characters with the same frequencies.

Rules:

In simple terms, it’s a frequency matching problem.

Examples:

isAnagram("anagram", "nagaram");  // true
isAnagram("rat", "car");          // false
isAnagram("listen", "silent");    // true
isAnagram("hello", "world");      // false

🧩 Understanding the Algorithm

To determine if two strings are anagrams, we need to check that both strings have the same characters with the same frequencies.

Key Observations:

  1. The strings must have the same length; otherwise, they can’t be anagrams.

  2. We need to check that each character in s appears the same number of times in t.


βœ… JavaScript Solution using Frequency Count (Array) β€” Best Solution

The most efficient solution in terms of time complexity is using a frequency count with a fixed-size array for storing character counts. This approach runs in O(n) time and O(1) space, making it the fastest for large strings.

/**
 * Determines if two strings are anagrams.
 * @param {string} s - First string
 * @param {string} t - Second string
 * @return {boolean}
 */
var isAnagram = function(s, t) {
    if (s.length !== t.length) return false;

    const count = new Array(26).fill(0);  // Count array for 'a' to 'z'

    // Count the frequency of each character
    for (let i = 0; i < s.length; i++) {
        count[s.charCodeAt(i) - 'a'.charCodeAt(0)]++;
        count[t.charCodeAt(i) - 'a'.charCodeAt(0)]--;
    }

    // Check if all counts are 0 (all frequencies match)
    return count.every(c => c === 0);
};

How it works:

πŸ•’ Time Complexity:


βœ… JavaScript Solution using Hash Map

Another efficient solution is to use a hash map to count the frequency of characters in both strings. It runs in O(n) time, but it uses O(n) space due to the hash map storage.

/**
 * Determines if two strings are anagrams.
 * @param {string} s - First string
 * @param {string} t - Second string
 * @return {boolean}
 */
var isAnagram = function(s, t) {
    if (s.length !== t.length) return false;
    const map = {};

    // Count characters in s
    for (let char of s) {
        map[char] = (map[char] || 0) + 1;
    }

    // Decrease the count for characters in t
    for (let char of t) {
        if (!map[char]) return false;
        map[char] -= 1;
    }

    return true;
};

How it works:

πŸ•’ Time Complexity:


βœ… JavaScript Solution using Sorting

While sorting is a simple and elegant solution, it is less efficient than the previous two approaches due to its O(n log n) time complexity. Sorting both strings and comparing them works, but it can be slower for larger inputs.

/**
 * Determines if two strings are anagrams.
 * @param {string} s - First string
 * @param {string} t - Second string
 * @return {boolean}
 */
var isAnagram = function(s, t) {
    if (s.length !== t.length) return false;

    // Sort both strings and compare
    return s.split('').sort().join('') === t.split('').sort().join('');
};

How it works:

πŸ•’ Time Complexity:


πŸ“Œ Notes & Gotchas


⏱ Complexity Analysis Summary

Approach Time Complexity Space Complexity
Frequency Count (Array) O(n) O(1)
Hash Map Approach O(n) O(n)
Sorting O(n log n) O(n)

πŸ”— Reference

Leetcode: Valid Anagram