Understand
30-second explanation
Build the interview-ready mental model before comparing implementations.
In camelCase the first word starts lowercase and every later word begins with an uppercase letter. So the number of words equals the number of uppercase letters plus one. Scan once, count uppercase characters, return count + 1. O(n) time, O(1) space.
Interview contextWhat is testedWhere candidates slipHow to stand outExplore interview contextHide interview context
What's being tested
Whether you spot the bijection between uppercase letters and word boundaries, avoiding an unnecessary split into substrings just to call size().
Where candidates slip
Splitting the string with a regex on case changes and counting the parts — correct but allocates a list and is easy to get wrong on edge cases like a leading capital.
How to stand out
State the invariant out loud: 'first word has no marker, every other word starts with exactly one uppercase, so words = uppercase + 1', and call out the empty-string exception.
Choose
Compare the available approaches
Use constraints and trade-offs to select the route you can defend in an interview.
Interactive decision treeInteractiveChoose the right approachExplore the full treeCollapse the tree
How to read it:Every capital begins a new word; the first word needs no marker, hence the +1.
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 2
Split on Case Changes (Naive)
1Hint 1Explore hintHide hint
You could insert a delimiter before every uppercase letter, then split into tokens and count them.
2Hint 2Explore hintHide hint
A regex like splitting before each capital, or a manual builder that adds a space before uppercase, gives you the words.
3Hint 3Explore hintHide hint
It works, but you allocate an array of substrings only to read its length — can the count come for free?
A · Core idea
The direct approach tokenises the string into the actual words, then returns how many there are. You walk the input, start a new token whenever you hit an uppercase letter, collect the tokens, and report the size.
Why it is correct. A case change is the only word boundary in camelCase, so cutting at every uppercase letter recovers exactly the original words. The number of tokens is the answer.
Why it is heavier than needed. To get a single integer you allocated a whole list of substrings (and possibly a rebuilt, space-separated copy of the input). That is O(n) extra memory and a lot of moving parts — regex edge cases, leading-empty-token handling, and so on. Since the question only asks how many words, you never actually need the words themselves.
The takeaway. Producing the tokens answers a harder question than was asked. Recognising that 'count of words' is fully captured by 'count of boundary markers' lets you drop the allocation entirely.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
s = "oneTwoThree"Mark breaks
before 'T' and 'T'
"one|Two|Three"3C · Code with teaching comments
Reference implementation previewpublic int camelcase(String s) { if (s.isEmpty()) { return 0; } String spaced = s.replaceAll("(?=[A-Z])", " ").trim();Explore the full codeHide the full code
D · Why it works and complexityO(n) timeO(n) spaceOpen the invariant and proofExplore the proofHide the proof
If a regex split produces a leading empty token (e.g. when the string starts with a capital in PascalCase), your count is off by one — exactly the kind of edge case the counting approach sidesteps.
ComplexityO(n) time, O(n) space — Building the delimited string and splitting both touch every character, so O(n) time, and the resulting list of words plus the rebuilt string cost O(n) space.
E · Edge cases and pitfalls3A leading empty token when the string starts with a capital — off-by-one.Explore edge casesHide edge cases
Pitfalls
- A leading empty token when the string starts with a capital — off-by-one.
- Allocating a token list purely to call length/len.
- Regex subtleties (greedy vs anchored) that differ between Java and Python.
Approach 2 of 2 · Optimal
Count Uppercase Letters + 1 (Optimal)
1Hint 1Explore hintHide hint
Every word after the first begins with exactly one uppercase letter. What does that say about the relationship between capitals and words?
2Hint 2Explore hintHide hint
Capitals and 'new word' events are in one-to-one correspondence. The first word has no capital, so seed your count at 1.
3Hint 3Explore hintHide hint
Scan once, add 1 for every uppercase letter, return the running total. No splitting, no extra memory.
A · Core idea
Initialise a word counter to 1 and increment it by one for every uppercase letter you encounter. Return the counter.
Why the seed is 1. camelCase always opens with a lowercase word that carries no marker. That first word exists regardless of how many capitals follow, so it is counted up front. If you seeded at 0, an all-lowercase string like "hello" would wrongly return 0 instead of 1.
Why each capital adds exactly one word. The convention guarantees that a new word begins precisely at an uppercase letter, and a word starts with a single capital — the rest of the word is lowercase. So there is a clean bijection: one uppercase letter ⇔ one new word boundary. Summing the boundaries and adding the unmarked first word gives uppercase_count + 1.
Why this beats splitting. You answer the exact question asked — how many words — without ever materialising the words. There is no token list, no regex, no leading-empty-token trap. The only state is one integer, so the space is constant and the logic has almost no surface area for bugs.
The one exception to remember. An empty string has zero words, but uppercase_count + 1 would return 1. Guard for empty input first when the constraints permit it, then apply the formula.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
s = "saveChangesInTheEditor"Array state
seed
first word 'one' → words = 1
5C · Code with teaching comments
D · Why it works and complexityO(n) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
The trick is recognising the bijection: in camelCase, 'number of word boundaries' literally equals 'number of uppercase letters'. Once boundaries map to a countable per-character property, you collapse a tokenising problem into a single counting loop.
ComplexityO(n) time, O(1) space — One pass over n characters with a constant-time uppercase test each → O(n) time. Only an integer counter is kept → O(1) space.
E · Edge cases and pitfalls6s = "a" — No capitals → 0 + 1 = 1 word.Explore edge casesHide edge cases
Edge cases handled
s = "a"No capitals → 0 + 1 = 1 word.s = "alllowercase"Still one word; the seed handles the all-lowercase case.s = "" (if permitted)Guard returns 0 — empty has no words, not one.
Pitfalls
- Seeding the count at 0 — an all-lowercase string then returns 0 instead of 1.
- Forgetting the empty-string guard — the formula returns 1 for no words.
- Assuming PascalCase: a leading capital would be over-counted by the +1.
Practice
Try the solution yourself
Edit the optimal implementation, test another input, and observe the result.
Editable code previewpublic int camelcase(String s) { if (s.isEmpty()) { return 0; } int words = 1;Explore the playgroundClose the playground
Avoid mistakes
Recognize the interview traps
Understand why common attempts fail before reviewing the corrected implementation.
1Forgetting the +1 for the first word
The first word has no uppercase marker, so counting only capitals undercounts by one for every camelCase string.
Explore the code comparisonHide the code comparison
Forgetting the +1 for the first word
The first word has no uppercase marker, so counting only capitals undercounts by one for every camelCase string.
Don't write this
int words = 0;
for (char c : s.toCharArray()) {
if (Character.isUpperCase(c)) words++;
}
return words;Write this instead
int words = 1;
for (char c : s.toCharArray()) {
if (Character.isUpperCase(c)) words++;
}
return words;2Off-by-one from a leading empty token
Splitting before each capital on a PascalCase string yields an empty first token, inflating the count by one.
Explore the code comparisonHide the code comparison
Off-by-one from a leading empty token
Splitting before each capital on a PascalCase string yields an empty first token, inflating the count by one.
Don't write this
return len(re.split(r'(?=[A-Z])', s))Write this instead
return 1 + sum(1 for c in s if c.isupper())3Returning 1 for an empty string
An empty input contains zero words, but the +1 formula returns 1 unless you guard for emptiness first.
Explore the code comparisonHide the code comparison
Returning 1 for an empty string
An empty input contains zero words, but the +1 formula returns 1 unless you guard for emptiness first.
Don't write this
return 1 + sum(1 for c in s if c.isupper())Write this instead
if not s:
return 0
return 1 + sum(1 for c in s if c.isupper())Revise
Carry the pattern into the interview
Pattern to remember
Word count = uppercase count + 1
Code pattern to memorize
words = 1
for c in s:
if c.isUpperCase():
words += 1
return wordsRules to remember
- 1Each new word (after the first) is signalled by exactly one uppercase letter — so uppercase letters and word-boundaries are in bijection.
- 2Start the count at 1 for the leading lowercase word, then add one per uppercase letter.
- 3Empty string is a special case: there are zero words, not one — guard for it if the constraints allow empty input.
- 4Detect uppercase with
Character.isUpperCase(c)/c.isupper(), not an ASCII range you might get wrong. - 5You never split the string — splitting allocates; counting does not.
Use this pattern when
- Tokens are delimited by a case change rather than a separator character
- You only need the count of tokens, not the tokens themselves
- The first token is special (no leading delimiter) so you seed the count at 1
- A single linear scan over characters suffices
Choose another pattern when
- Words are separated by spaces or punctuation → split on the delimiter instead
- You must return the actual words → you build a list, not a counter
- Mixed conventions (snake_case + camelCase) appear → counting uppercase alone is wrong
- PascalCase where the first word is also capitalised → the +1 seed changes
Interview takeaway
When token boundaries are marked by a property of a single character (a case change), counting that property and adjusting for the first token gives the count in one pass — far cheaper than splitting into substrings.
Continue
Transfer the pattern to another problem
Use a direct variation or pattern sibling to prove the idea is reusable.
Transferable patternBoundary-marker counting. When tokens are delimited by a per-character property (here, an uppercase letter) and you only need the count, tally that property in one pass and adjust for the unmarked first token instead of splitting into substrings.
Practice queueDirect variations and pattern siblings
Direct follow-ups
- CamelCase to snake_caseComing soonNow you must emit the words: insert '_' before each capital and lowercase it.
- Count words in PascalCaseComing soonFirst word is also capitalised, so words = uppercase count (no +1).
- Split camelCase into the actual wordsComing soonReturn the tokens — the harder version where allocation is unavoidable.
- Goat LatinComing soonPer-word transformation that also keys off word boundaries and casing.