Anagram Check Techniques in DSA Typescript - Time & Space Complexity
We want to know how the time needed to check if two words are anagrams changes as the words get longer.
How does the method we use affect the time it takes?
Analyze the time complexity of the following code snippet.
function areAnagrams(s1: string, s2: string): boolean {
if (s1.length !== s2.length) return false;
const count: Record = {};
for (const char of s1) {
count[char] = (count[char] || 0) + 1;
}
for (const char of s2) {
if (!count[char]) return false;
count[char]--;
}
return true;
}
This code checks if two strings are anagrams by counting characters in the first and matching counts with the second.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Two loops each going through all characters of the strings.
- How many times: Each loop runs once for every character, so twice the length of the strings.
As the strings get longer, the number of steps grows roughly twice as much because we check each character twice.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 20 steps |
| 100 | About 200 steps |
| 1000 | About 2000 steps |
Pattern observation: The time grows linearly with the length of the strings.
Time Complexity: O(n)
This means the time to check anagrams grows in direct proportion to the length of the strings.
[X] Wrong: "Sorting both strings is always faster than counting characters."
[OK] Correct: Sorting takes more time (O(n log n)) than counting characters (O(n)) for long strings, so counting is usually faster.
Understanding how different ways to check anagrams affect time helps you choose the best method in real problems.
"What if we used sorting both strings instead of counting characters? How would the time complexity change?"
Practice
Solution
Step 1: Understand the definition of anagrams
Anagrams are words or phrases made by rearranging the letters of another, so they must have the same characters.Step 2: Compare the character sets
If two strings have exactly the same characters, just in different orders, they are anagrams.Final Answer:
They contain the same characters in any order -> Option AQuick Check:
Anagrams = same characters [OK]
- Thinking same length means anagrams
- Only comparing first or last characters
- Ignoring character counts
Solution
Step 1: Understand string sorting in TypeScript
Strings must be split into arrays, sorted, then joined back to strings for comparison.Step 2: Identify correct syntax
const isAnagram = (a: string, b: string) => a.split('').sort().join('') === b.split('').sort().join(''); correctly splits, sorts, and joins both strings before comparing.Final Answer:
const isAnagram = (a: string, b: string) => a.split('').sort().join('') === b.split('').sort().join(''); -> Option AQuick Check:
Sort and join strings before compare [OK]
- Comparing arrays directly without join
- Trying to sort strings directly
- Comparing strings without sorting
function areAnagrams(s1: string, s2: string): boolean {
const normalize = (str: string) => str.toLowerCase().replace(/\s+/g, '').split('').sort().join('');
return normalize(s1) === normalize(s2);
}
console.log(areAnagrams('Listen', 'Silent'));
console.log(areAnagrams('Hello', 'Olelh'));
console.log(areAnagrams('Test', 'Taste'));Solution
Step 1: Normalize strings by lowercasing, removing spaces, sorting
'Listen' and 'Silent' normalize to 'eilnst', 'Hello' and 'Olelh' normalize to 'ehllo', 'Test' and 'Taste' normalize to 'estt' and 'aestt' respectively.Step 2: Compare normalized strings
'Listen' vs 'Silent' match (true), 'Hello' vs 'Olelh' match (true), 'Test' vs 'Taste' do not match (false).Final Answer:
true true false -> Option BQuick Check:
Normalized strings equal means true [OK]
- Ignoring case differences
- Not removing spaces
- Not sorting characters
function isAnagram(a: string, b: string): boolean {
return a.split('').sort() === b.split('').sort();
}Solution
Step 1: Understand array comparison in TypeScript
Arrays compared with === check reference, not content, so two sorted arrays won't be equal even if same elements.Step 2: Fix by joining arrays to strings before comparing
Joining sorted arrays to strings allows content comparison, fixing the bug.Final Answer:
Comparing arrays directly instead of strings -> Option CQuick Check:
Arrays need join() before compare [OK]
- Comparing arrays with ===
- Ignoring case sensitivity
- Not trimming spaces
Solution
Step 1: Understand character count map approach
Count characters in first string, subtract counts using second string, then check all counts zero.Step 2: Analyze each option
function isAnagram(a: string, b: string): boolean { if (a.length !== b.length) return false; const count: Record = {}; for (const char of a) count[char] = (count[char] || 0) + 1; for (const char of b) { if (!count[char]) return false; count[char]--; } return true; } misses checking if count goes negative; function isAnagram(a: string, b: string): boolean { return a.split('').sort().join('') === b.split('').sort().join(''); } uses sorting (correct but not map); function isAnagram(a: string, b: string): boolean { return a.length === b.length; } only checks length; function isAnagram(a: string, b: string): boolean { const mapA = new Map(); for (const c of a) mapA.set(c, (mapA.get(c) || 0) + 1); for (const c of b) mapA.set(c, (mapA.get(c) || 0) - 1); return [...mapA.values()].every(v => v === 0); } correctly uses Map to count and verify zero counts.Final Answer:
Option D correctly implements character count map with Map and zero check -> Option DQuick Check:
Map counts increment/decrement, all zero means anagram [OK]
- Not checking for negative counts
- Only comparing lengths
- Using sorting instead of counting
Ready to prove it?
Pass the test and this pattern moves unknown
