Understand
30-second explanation
Build the interview-ready mental model before comparing implementations.
Don't build the giant string — n can be up to 10¹². Count 'a' in one copy of s, multiply by the number of complete copies that fit (n // len(s)), then add the 'a' count in the leftover prefix s[: n % len(s)]. Answer = (n // L) * countA + count of 'a' in the first (n % L) characters.
Interview contextWhat is testedWhere candidates slipHow to stand outExplore interview contextHide interview context
What's being tested
Whether you spot that n up to 10¹² forbids building the string, and instead decompose the count into full repeats (multiply) plus a remainder prefix (count once).
Where candidates slip
Constructing the repeated string (s * (n // len(s) + 1))[:n] and counting — correct logic but O(n) memory/time that times out and can crash for n = 10¹².
How to stand out
Derive the formula from divmod, call out the long-overflow risk in Java, and note the edge case where n < len(s) is handled automatically by the same expression.
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:The first n characters = (n // L) whole copies of s + a prefix of length n % L.
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
Build the String, Then Count (Naive — Don't Ship)
1Hint 1Explore hintHide hint
The literal interpretation: physically create the first n characters and count 'a'. What does n = 10¹² do to that plan?
2Hint 2Explore hintHide hint
Repeat s enough times to reach length n, slice to exactly n, then count 'a'.
3Hint 3Explore hintHide hint
Now estimate memory: 10¹² characters ≈ a terabyte. This approach cannot run — that realisation is the whole lesson.
A · Core idea
The most direct reading of the problem is 'make the first n characters, then count the a's'. It is worth articulating because it is what most people picture first — and then immediately rejecting it.
Why it is tempting. It maps one-to-one onto the words of the problem: the string is s repeated, so build s repeated, slice to n, count. The logic is trivially correct.
Why it is fatal here. The constraint n ≤ 10¹² is not decoration — it is the adversary. A trillion characters is on the order of a terabyte of memory and a trillion character comparisons. The program will exhaust memory or time out long before it answers. This is the textbook case where a correct algorithm is still wrong for the input size.
The lesson it teaches. Whenever a problem hands you an absurdly large bound, it is signalling that the intended solution does not touch every element. Here that nudge points straight at periodicity: the string repeats, so we should count once per period and scale arithmetically rather than enumerate.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
s = "aba", n = 10Repeat
tile "aba" until length ≥ 10
"abaabaabaa..."7 (but infeasible for n = 10¹²)C · Code with teaching comments
Reference implementation previewpublic long repeatedString(String s, long n) { StringBuilder sb = new StringBuilder(); while (sb.length() < n) { sb.append(s); }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
A huge input bound is a hint, not a detail. n = 10¹² is the problem telling you 'you may not build me' — read the constraints before you commit to an approach.
ComplexityO(n) time, O(n) space — Constructing and scanning n characters is O(n) time and O(n) space. For n = 10¹² that is ~1 TB of memory and a trillion operations — infeasible.
E · Edge cases and pitfalls4s = "a", n = 1000000000000 — Tries to allocate ~10¹² characters → MemoryError / OutOfMemoryError. Demonstrates why we need the math approach.Explore edge casesHide edge cases
Edge cases handled
s = "a", n = 1000000000000Tries to allocate ~10¹² characters → MemoryError / OutOfMemoryError. Demonstrates why we need the math approach.
Pitfalls
- Believing 'correct logic' is enough — it must also fit the input bounds.
- Casting a 10¹² value to int (Java) silently overflows.
- Ignoring the constraints section before choosing an approach.
Approach 2 of 2 · Optimal
Integer Math — Full Repeats + Remainder Prefix (Optimal)
1Hint 1Explore hintHide hint
You never need the whole string — only how many 'a' are in its first n characters. The string is periodic with period L = |s|. How many complete periods fit in n, and what's left over?
2Hint 2Explore hintHide hint
n splits as n = (n // L) complete copies of s, plus a leftover prefix of length n % L. Each complete copy has exactly the same number of 'a'.
3Hint 3Explore hintHide hint
Count 'a' once in s, multiply by n // L, then add the 'a' count in s[: n % L]. Done in O(|s|), no giant string.
A · Core idea
Because the string is s tiled infinitely, the first n characters have a rigid structure: a whole number of complete copies of s followed by one partial copy. Express that with one divmod: fullCopies = n // L and remainder = n % L, where L = |s|.
Why multiplication replaces a loop. Every complete copy of s is character-for-character identical, so each contributes exactly the same number of 'a' — call it countA = count of 'a' in s. Instead of scanning fullCopies copies, we scan s once and multiply: fullCopies * countA. That single multiplication is where the trillion-scale n gets tamed — n only ever appears inside cheap integer division and a product, never as a loop bound.
Why the remainder prefix. After the whole copies, the first n characters include the leading remainder characters of the next copy — that's s[: remainder]. We count 'a' in just those characters and add it. We deliberately count the prefix of s, not an arbitrary slice, because the infinite string always restarts s from index 0 after each copy.
Why `n < L` needs no special case. If n is smaller than one copy, fullCopies = n // L = 0, so the first term vanishes and remainder = n, making the answer purely count of 'a' in s[: n]. The same expression handles small and huge n identically — no branching required.
Why `long` in Java. With s = "a" and n = 10¹², the result is 10¹², far beyond int's ~2.1×10⁹ ceiling. Declare n and the running total as long, or the product overflows to a wrong (often negative) value. Python's arbitrary-precision ints make this free.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
s = "aba", n = 10Interactive diagram
Why no string is ever built
Per-copy countn flows only through division and a product — never a loop over n characters.
7C · Code with teaching comments
D · Why it works and complexityO(|s|) timeO(1) spaceOpen the invariant and proofExplore the proofHide the proof
The whole solution is one divmod: quotient → 'how many full periods' (multiply the per-period count), remainder → 'how much of the next period' (count its prefix). This quotient-plus-remainder decomposition is the universal way to answer 'how many X in the first n of something periodic' without ever expanding it.
ComplexityO(|s|) time, O(1) space — Counting 'a' in s is O(|s|); counting in the prefix is O(|s|) at most; the rest is constant-time arithmetic. Total O(|s|) time (≤ 100 ops) and O(1) extra space — completely independent of n.
E · Edge cases and pitfalls6s = "a", n = 1000000000000 — countA = 1, fullCopies = 10¹², remainder = 0 → 10¹² * 1 = 10¹². Needs long in Java; instant.Explore edge casesHide edge cases
Edge cases handled
s = "a", n = 1000000000000countA = 1, fullCopies = 10¹², remainder = 0 → 10¹² * 1 = 10¹². Needs long in Java; instant.s = "abc", n = 2n < L: fullCopies = 0, remainder = 2 → prefix "ab" has 1 'a' → returns 1.s = "bbb", n = 999999999999countA = 0 → total stays 0 regardless of n. No 'a' anywhere.
Pitfalls
- Using int instead of long in Java — the product overflows for large n.
- Counting 'a' in the full s for the remainder instead of only s[: remainder].
- Adding a needless special case for n < L — the formula already handles it via n // L = 0.
Practice
Try the solution yourself
Edit the optimal implementation, test another input, and observe the result.
Editable code previewpublic long repeatedString(String s, long n) { long countA = 0; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == 'a') countA++; }Explore the playgroundClose the playground
Avoid mistakes
Recognize the interview traps
Understand why common attempts fail before reviewing the corrected implementation.
1Materialising the giant string
n up to 10¹² means ~1 TB of characters. Even though counting is correct, the allocation crashes or times out. Use division/modulo math instead.
Explore the code comparisonHide the code comparison
Materialising the giant string
n up to 10¹² means ~1 TB of characters. Even though counting is correct, the allocation crashes or times out. Use division/modulo math instead.
Don't write this
return (s * (n // len(s) + 1))[:n].count('a')Write this instead
full, rem = divmod(n, len(s))
return full * s.count('a') + s[:rem].count('a')2Integer overflow in Java
With s = "a", n = 10¹², the answer is 10¹², which overflows a 32-bit int to a wrong value. The total and n must be long.
Explore the code comparisonHide the code comparison
Integer overflow in Java
With s = "a", n = 10¹², the answer is 10¹², which overflows a 32-bit int to a wrong value. The total and n must be long.
Don't write this
int total = (int) (fullCopies * countA);Write this instead
long total = fullCopies * countA;3Wrong remainder slice
The trailing partial copy is the FIRST n % L characters of s, not the whole copy. Counting all of s double-counts.
Explore the code comparisonHide the code comparison
Wrong remainder slice
The trailing partial copy is the FIRST n % L characters of s, not the whole copy. Counting all of s double-counts.
Don't write this
return full * s.count('a') + s.count('a')Write this instead
return full * s.count('a') + s[:rem].count('a')Revise
Carry the pattern into the interview
Pattern to remember
Full-repeats × per-copy count + remainder prefix
Code pattern to memorize
L = len(s)
fullCopies = n // L
remainder = n % L
total = fullCopies * count(s, 'a')
+ count(s[:remainder], 'a')Rules to remember
- 1Never materialise the repeated string — n up to 10¹² means the string would have a trillion characters and blow memory/time.
- 2Split the first n characters into
n // Lwhole copies plus one partial prefix of lengthn % L. - 3Each whole copy contributes the same count of 'a' → multiply, don't loop.
- 4Use
intmath; in Java the product can exceedintrange, so the total must be `long`. - 5The remainder prefix is
s[: n % L]— count 'a' only in those leading characters, not the whole copy. - 6If
n < L, thenn // L = 0and the answer is purely the prefix count — the formula still works.
Use this pattern when
- A value is conceptually huge/infinite but periodic, so you can reason per-period
- You'd otherwise construct an enormous structure just to count something
- The query is 'how many X in the first n of a repeating pattern'
- Counting within one period is cheap and the rest is multiplication
Choose another pattern when
- The pattern is not periodic / each position is unique → no per-period shortcut
- n is tiny and constant → just build it; the math is overkill
- You must return the actual characters, not a count → can't avoid materialising what you output
- The 'period' changes over time → it isn't a fixed repeat
Interview takeaway
When something repeats infinitely, count within one period and scale with division/modulo — never build the whole thing. This 'quotient × per-period + remainder' decomposition is the same trick behind clock arithmetic, cycle detection, and 'nth digit of a repeating sequence' problems.
Continue
Transfer the pattern to another problem
Use a direct variation or pattern sibling to prove the idea is reusable.
Transferable patternPeriodic decomposition with divmod. When a structure repeats, split a query over its first n elements into (n // period) whole periods plus a remainder prefix, counting once per period and scaling by multiplication. Never expand the full structure.
Practice queueDirect variations and pattern siblings
Direct follow-ups
- Count any character c in first nComing soonReplace 'a' with a parameter c — the divmod decomposition is identical.
- Sum of first n digits of a repeating decimalComing soonSame quotient × per-period + remainder idea applied to a periodic digit sequence.
- Smallest Integer Divisible by KComing soonReasoning about repeated/periodic structure with modular arithmetic instead of construction.
- Lily's Homework / Cyclic patternsComing soonAnother HackerRank-style problem where periodicity replaces brute enumeration.