top of page

Valid Anagram

  • mosesg1123
  • Apr 16
  • 4 min read

Updated: Apr 22


Today, I’m tackling the Valid Anagram problem, a classic that not only tests basic string manipulation but also real‑world pattern matching. This problem is a great warm‑up because it uses simple techniques that have many applications!


Problem Statement

Given two strings s and t, determine if t is an anagram of s. An anagram is formed by rearranging the letters of another string, using every letter exactly once. The solution should return True if t is an anagram of s, and False otherwise.


1. Clarify Requirements Before Jumping Into Code

I need to confirm a couple of details first. I assume both strings consist of lowercase English letters. If the lengths differ, the answer is immediately False. I’ll need to decide if I can change the strings or not; the question implies I shouldn’t need to modify them. Finally, I confirm that I'm comparing overall frequency of each letter, not position or order.


2. Identify the Category of the Question

This is a string manipulation problem that involves counting frequencies, an ideal fit for a hash table or fixed‑size array approach. It belongs to the categories of hashing and frequency counting, which I often see when checking if two data collections are equivalent regardless of order.


3. Consider a Brute‑Force Approach to Understand the Problem

A straightforward, if not optimal, solution might be to generate all permutations of s and check if t is one of those. However, this method would be extremely inefficient with factorial time complexity, making it impractical for even moderately sized strings.

I could also go letter by letter, comparing every character in one string against all the strings in the other. This is O(n^2) time which is also inefficient. But this idea of comparing letters in each string is on the right track, I just need a data structure that will help me look up what characters I've seen before in constant time!


4. Brainstorm More Solutions

A better method is to count the characters in each string and compare their frequency. I could do this by sorting both strings and comparing if they are identical, or by using a hash map (or fixed‑size array) to tally character counts and then compare these counts. Sorting will give me O(n log n) time, while the hash table method can achieve O(n) time complexity.


5. Discuss Trade‑Offs Between Your Solutions

  • Brute‑Force (Permutation):

    • Time Complexity: O(n!)

    • Space Complexity: O(n)

    • Pros: Conceptually simple.

    • Cons: Not feasible for practical input sizes.

  • Sorting:

    • Time Complexity: O(n log n)

    • Space Complexity: Depends on sorting algorithm; can be O(1) if in-place.

    • Pros: Easy to implement with built‑ins; clear logic.

    • Cons: Not optimal if an O(n) solution exists.

  • Hash Table / Fixed‑Size Array:

    • Time Complexity: O(n)

    • Space Complexity: O(1) if using a fixed‑size array for 26 letters.

    • Pros: Fast and efficient; optimal for this problem.

    • Cons: Slightly more code required for counting.

The hash table solution is ideal here.


6. Write Pseudocode to Structure Your Thoughts

function isAnagram(s, t):
    if length(s) ≠ length(t):
        return False

    initialize count array or hash map for letters

    for each character c in s:
        increment count[c]

    for each character c in t:
        decrement count[c]
        if count[c] < 0:
            return False

    return True

7. Consider Edge Cases

  • Two empty strings: both should return True.

  • One empty string and one non‑empty string: return False.

  • Strings of different lengths: return False immediately.

  • Identical strings: return True.

  • Strings with repeated characters, ensuring counts match exactly.


8. Write Full Code Syntax

def is_anagram(s, t):
    # If lengths differ, cannot be anagrams
    if len(s) != len(t):
        return False

    # Using a fixed-size list for 26 lowercase letters
    count = [0] * 26
    # Process first string
    for char in s:
        count[ord(char) - ord('a')] += 1
    
    # Process second string
    for char in t:
        count[ord(char) - ord('a')] -= 1
        if count[ord(char) - ord('a')] < 0:
            return False
    
    # If all counts are zero, strings are anagrams
    return True

9. Test Your Code

# Test Case 1: Simple anagram
s1 = "anagram"
t1 = "nagaram"
assert is_anagram(s1, t1) == True

# Test Case 2: Not an anagram
s2 = "rat"
t2 = "car"
assert is_anagram(s2, t2) == False

# Test Case 3: Empty strings
s3 = ""
t3 = ""
assert is_anagram(s3, t3) == True

# Test Case 4: Different lengths
s4 = "hello"
t4 = "billion"
assert is_anagram(s4, t4) == False

# Test Case 5: Same letters but different frequency
s5 = "aabbcc"
t5 = "abcabc"
assert is_anagram(s5, t5) == True

print("All tests passed!")

10. Key Lessons to Remember for Future Questions

  • When checking for anagrams or similar problems, think in terms of character counts and frequency matching.

  • If input sizes allow, always check the lengths first as a quick fail condition.

  • Hash table or fixed-size array techniques can reduce time complexity to O(n) for counting problems.

  • Sorting is a viable alternative, but in this case, it won’t beat a direct frequency count in terms of efficiency.

  • Always test for edge cases, particularly with empty strings or mismatched string lengths.

  • Clear communication about your thought process is essential; it shows you’re methodical and efficient in designing solutions.


Happy coding!

Recent Posts

See All
Non-Overlapping Intervals

Learn how to solve the Non-Overlapping Intervals coding problem to prepare for your next technical interview!

 
 
 
Merge Intervals

"Merge Intervals" is one of those classic algorithm problems that shows up frequently in technical interviews. It's a great test of your...

 
 
 
Jump Game II

Jump Game II is a classic follow-up to the original Jump Game problem. It’s not just about whether you can reach the end... now you have to do it in the fewest jumps possible! That small change turns

 
 
 

Comments


Drop Me a Line, Let Me Know What You Think

Thanks for submitting!

© 2023 by Train of Thoughts. Proudly created with Wix.com

bottom of page