Anagram Check Techniques in DSA C# - Time & Space Complexity
We want to understand how the time needed to check if two words are anagrams changes as the words get longer.
How does the work grow when the input size increases?
Analyze the time complexity of the following code snippet.
// Check if two strings are anagrams by sorting
bool AreAnagrams(string s1, string s2) {
if (s1.Length != s2.Length) return false;
var arr1 = s1.ToCharArray();
var arr2 = s2.ToCharArray();
Array.Sort(arr1);
Array.Sort(arr2);
for (int i = 0; i < arr1.Length; i++) {
if (arr1[i] != arr2[i]) return false;
}
return true;
}
This code checks if two strings are anagrams by sorting their characters and comparing them.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Sorting both character arrays and then comparing them.
- How many times: Sorting runs in about n log n time, and the comparison loop runs n times, where n is the string length.
As the strings get longer, sorting takes more time, growing faster than just checking each character.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 * log(10) ≈ 33 operations |
| 100 | About 100 * log(100) ≈ 664 operations |
| 1000 | About 1000 * log(1000) ≈ 9965 operations |
Pattern observation: The work grows faster than the input size but slower than the square of the input size.
Time Complexity: O(n log n)
This means the time needed grows a bit faster than the length of the strings but not as fast as checking every pair of characters.
[X] Wrong: "Comparing characters one by one without sorting is always faster."
[OK] Correct: Without sorting or counting, you might miss differences in character counts, so a simple one-by-one check can fail to detect anagrams correctly.
Understanding how sorting affects time helps you explain your choices clearly and shows you know how to balance speed and correctness.
"What if we used a character count array instead of sorting? 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 with the same counts.Step 2: Compare the options
Only They have the same characters in the same frequency but possibly different order correctly describes this property; others describe unrelated conditions.Final Answer:
They have the same characters in the same frequency but possibly different order -> Option AQuick Check:
Anagram = Same chars & frequency [OK]
- Thinking same length means anagram
- Assuming order must be identical
- Confusing anagrams with substrings
Solution
Step 1: Understand sorting approach for anagrams
Sorting both strings and comparing them checks if they have the same characters in the same order after sorting.Step 2: Analyze each code snippet
return string.Concat(s1.OrderBy(c => c)) == string.Concat(s2.OrderBy(c => c)); sorts both strings and compares; this is correct. Options B, C, and D do not check anagram conditions properly.Final Answer:
return string.Concat(s1.OrderBy(c => c)) == string.Concat(s2.OrderBy(c => c)); -> Option DQuick Check:
Sort & compare strings = correct anagram check [OK]
- Comparing strings directly without sorting
- Only checking length equality
- Using Contains instead of full comparison
string s1 = "listen"; string s2 = "silent"; bool result = s1.OrderBy(c => c).SequenceEqual(s2.OrderBy(c => c)); Console.WriteLine(result);
Solution
Step 1: Sort both strings and compare sequences
The code sorts characters of both strings and checks if sequences are equal. "listen" and "silent" are anagrams.Step 2: Evaluate the result of SequenceEqual
Since sorted characters match, SequenceEqual returns true, so Console.WriteLine prints True.Final Answer:
True -> Option AQuick Check:
Sorted anagrams equal = True [OK]
- Assuming order matters before sorting
- Confusing SequenceEqual with Equals
- Expecting false because strings differ initially
bool AreAnagrams(string s1, string s2) {
if (s1.Length != s2.Length) return false;
var dict = new Dictionary();
foreach (var c in s1) {
dict[c] = dict.ContainsKey(c) ? dict[c] + 1 : 1;
}
foreach (var c in s2) {
if (!dict.ContainsKey(c)) return false;
dict[c]--;
}
return true;
}Solution
Step 1: Review dictionary count decrement logic
The method decrements counts for characters in s2 but never checks if count becomes negative, which means extra characters in s2 are not detected.Step 2: Identify missing validation
Without checking if dict[c] < 0 after decrement, method can wrongly return true when s2 has extra characters.Final Answer:
It does not check if counts go below zero -> Option CQuick Check:
Check negative counts after decrement to fix bug [OK]
- Ignoring negative counts after decrement
- Assuming length check is enough
- Not using dictionary for frequency
Solution
Step 1: Normalize strings by removing spaces and converting to lowercase
This ensures spaces and case differences do not affect comparison.Step 2: Sort normalized strings and compare
Sorting both normalized strings and comparing confirms if they are anagrams ignoring case and spaces.Final Answer:
Remove spaces, convert to lowercase, then sort and compare -> Option BQuick Check:
Normalize then sort & compare for case/space insensitive anagram [OK]
- Not removing spaces before comparison
- Ignoring case differences
- Only checking length equality
Ready to prove it?
Pass the test and this pattern moves unknown
