Understand
30-second explanation
Build the interview-ready mental model before comparing implementations.
Iterate the characters, doing `freq[ch] = freq.getOrDefault(ch, 0) + 1`. The map is the frequency table.
Interview contextWhat is testedWhere candidates slipHow to stand outExplore interview contextHide interview context
What's being tested
Whether you build a frequency map and handle the first-sighting default.
Where candidates slip
NPE on a new key, or wrong case handling.
How to stand out
Offer the int[26] array for a fixed lowercase alphabet.
Choose
Compare the available approaches
Use constraints and trade-offs to select the route you can defend in an interview.
Learn & trace
Build each solution step by step
Move from the core idea to a visual trace, implementation, proof, and edge cases.
Approach 1 of 1 · Optimal
Hash map counting
1Hint 1Explore hintHide hint
Map each character to a running count.
2Hint 2Explore hintHide hint
Use a default of 0 for first sightings.
3Hint 3Explore hintHide hint
Decide case sensitivity explicitly.
A · Core idea
Build a hash map from character to count in one pass — the string twin of the array frequency map, and the seed for anagrams, first-unique-character, and many string problems.
Why getOrDefault / Counter. On a character's first appearance there's no entry yet; getOrDefault(ch, 0) (Java) or collections.Counter (Python) supplies the implicit 0 so you don't NullPointer / KeyError.
Case sensitivity. Decide up front whether 'A' and 'a' are the same key. Lower-casing first merges them; keeping them distinct is also valid — just be explicit so it matches the spec.
Array alternative. For a known small alphabet (a–z), an int[26] is faster and O(1) space versus a hash map — worth mentioning.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
s = "aab"a
new → 1
{a:1}{a:2, b:1}C · Code with teaching comments
D · Why it works and complexityO(n) timeO(k) spaceOpen the invariant and proofExplore the proofHide the proof
ComplexityO(n) time, O(k) space — one O(1) map update per character; the map holds k ≤ alphabet-size keys.
E · Edge cases and pitfalls5s = "" — Empty map {}.Explore edge casesHide edge cases
Edge cases handled
s = ""Empty map {}.s = "xx"{x:2}.s = "Aa"Two keys if case-sensitive, one if folded.
Pitfalls
- No default for a first occurrence (NullPointerException in Java).
- Mismatching the case-sensitivity the prompt expects.
Practice
Try the solution yourself
Edit the optimal implementation, test another input, and observe the result.
Editable code previewpublic java.util.Map<Character, Integer> charFrequency(String s) { java.util.Map<Character, Integer> freq = new java.util.HashMap<>(); for (char ch : s.toCharArray()) { freq.put(ch, freq.getOrDefault(ch, 0) + 1); }Explore the playgroundClose the playground
Avoid mistakes
Recognize the interview traps
Understand why common attempts fail before reviewing the corrected implementation.
- No default for first occurrence (NullPointerException).
- Lower-casing when the prompt is case-sensitive (or vice versa).
Revise
Carry the pattern into the interview
Pattern to remember
Frequency map (chars)
Code pattern to memorize
for ch: freq[ch] = freq.get(ch,0)+1Rules to remember
- 1Key = char, value = count.
- 2getOrDefault for new keys.
- 3Foundation for anagram/unique-char.
Use this pattern when
- String counting, anagrams, unique-char
Interview takeaway
The character frequency map underlies most string-counting problems.
Continue
Transfer the pattern to another problem
Use a direct variation or pattern sibling to prove the idea is reusable.
Transferable patternA core fresher pattern: Frequency map (chars). Master it on small inputs and it transfers to harder problems.