Understand
30-second explanation
Build the interview-ready mental model before comparing implementations.
The array is a big integer, one digit per slot, most-significant first. To add one, walk from the RIGHT simulating grade-school addition with a carry. If a digit is less than 9, increment it and you're done — there's no carry to propagate. If it's 9, set it to 0 and continue left. The only case that grows the array is all 9s (e.g. 999 → 1000): after the loop a carry remains, so prepend a leading 1.
Interview contextWhat is testedWhere candidates slipHow to stand outExplore interview contextHide interview context
What's being tested
Whether you simulate positional addition with a carry instead of converting the array to a native integer (which overflows for large inputs), and whether you correctly handle carry propagation through trailing 9s — especially the array-growing all-9s case.
Where candidates slip
Joining digits into an int, adding 1, and splitting back — silently breaks once the number exceeds 64 bits. Or mishandling 999 → 1000 by forgetting to prepend the new leading digit.
How to stand out
Note up front that the array can represent a number too big for a long, so digit-by-digit carry is the robust approach. Mention the early return when a digit < 9 (no carry to propagate) and that only all-9s grows the array length.
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 approachFirst decision previewStart at rightmost digitdigits[i] < 9?YesNo (== 9)Explore the full treeCollapse the tree
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
Digit-by-Digit Carry (Optimal)
1Hint 1Explore hintHide hint
The array is a number written one digit per slot, most significant first. How did you add 1 to a number by hand in grade school? Which end did you start from?
2Hint 2Explore hintHide hint
Start at the LAST index. If that digit is less than 9, just add 1 and you're finished — there's no carry. Return right away.
3Hint 3Explore hintHide hint
If the digit is 9, adding 1 makes it 10: write a 0 and carry the 1 to the left. Keep going. If you run off the left end, every digit was 9 — prepend a leading 1.
A · Core idea
Read the array as a positional number and replay long-hand addition. The +1 enters at the least-significant digit (the rightmost slot), and a carry only ever moves leftward, so the loop walks from digits.length - 1 down to 0.
Why a digit less than 9 ends everything. When digits[i] < 9, adding one produces a value in 0..9 — a single digit, no overflow into the next place. So you increment that slot and return immediately. Crucially, all digits to its left are untouched and correct, which is why the early return is not just an optimization but the natural stopping point: there is no carry left to propagate.
Why a 9 turns into a 0 and keeps going. 9 + 1 = 10. In positional notation that's a 0 in the current place and a 1 carried to the next more-significant place. So we set digits[i] = 0 and continue the loop to apply that carry to digits[i-1]. Consecutive 9s create a ripple: each becomes 0 and hands the carry left until it finally meets a digit below 9 that absorbs it (the early return above).
Why only all-9s grows the array. If every digit is a 9, the carry never finds a digit to absorb it — the loop sets each to 0 and falls off the left edge with a pending carry. That pending carry is a brand-new most-significant digit. 999 + 1 = 1000 needs four slots for a three-slot input, so we allocate a fresh array of length n + 1, place a 1 at the front, and leave the rest as the zeros we just wrote. This is the one and only case where the length changes.
Why we don't parse to an integer. A tempting shortcut is Long.parseLong(join(digits)) + 1 then split back. With up to 100 digits, the value vastly exceeds 64-bit range and silently overflows. Digit-by-digit addition sidesteps overflow entirely and is the reason this 'easy' problem is really a big-integer arithmetic check.
B · Visual dry run
Interactive dry run
Select a frame to connect the decision with its visual state.
digits = [1, 2, 9]Array state
i=2
9 + 1 = 10 → write 0, carry
[1, 3, 0]C · Code with teaching comments
D · Why it works and complexityO(n) timeO(1) in place, O(n) only when the array grows spaceOpen the invariant and proofExplore the proofHide the proof
The whole problem hinges on one observation: adding 1 produces at most a single carry, and that carry dies the instant it meets any digit below 9. So the common case is O(1) work (increment the last digit and return), and the worst case (all 9s) is the only time the array grows. Recognizing 'carry stops at the first non-max digit' is what makes the early return obvious.
ComplexityO(n) time, O(1) in place, O(n) only when the array grows space — A single pass from right to left touches each of the n digits at most once → O(n). It mutates in place, so O(1) extra space; the only allocation is the new (n+1)-length array in the all-9s case, which is O(n) and rare.
E · Edge cases and pitfalls6digits = [9] — Single 9 → set to 0, loop ends, return [1, 0]. Smallest array-growing case.Explore edge casesHide edge cases
Edge cases handled
digits = [9]Single 9 → set to 0, loop ends, return [1, 0]. Smallest array-growing case.digits = [9, 9, 9]All become 0, carry survives → return [1, 0, 0, 0], length grows from 3 to 4.digits = [4, 3, 2, 1]Last digit 1 < 9 → increment to 2, return [4, 3, 2, 2]; no carry, O(1) work.
Pitfalls
- Iterating left to right — the carry direction is wrong; addition carries from least to most significant.
- Forgetting the all-9s case, returning an array of zeros without the leading 1.
- Parsing the digits into an int/long and adding — overflows for inputs beyond 64-bit range.
Practice
Try the solution yourself
Edit the optimal implementation, test another input, and observe the result.
Editable code previewpublic int[] plusOne(int[] digits) { for (int i = digits.length - 1; i >= 0; i--) { if (digits[i] < 9) { digits[i]++; return digits;Explore the playgroundClose the playground
Avoid mistakes
Recognize the interview traps
Understand why common attempts fail before reviewing the corrected implementation.
1Parsing to an integer (overflow)
With up to 100 digits the number far exceeds long range, so parse-add-split silently produces garbage or throws. Digit-by-digit addition is overflow-proof.
Explore the code comparisonHide the code comparison
Parsing to an integer (overflow)
With up to 100 digits the number far exceeds long range, so parse-add-split silently produces garbage or throws. Digit-by-digit addition is overflow-proof.
Don't write this
long num = Long.parseLong(join(digits)); // overflows for big inputs
num += 1;
return split(num);Write this instead
for (int i = digits.length - 1; i >= 0; i--) {
if (digits[i] < 9) { digits[i]++; return digits; }
digits[i] = 0;
}
int[] res = new int[digits.length + 1];
res[0] = 1;
return res;2Missing the all-9s array growth
If you only mutate in place and return the same array, [9,9,9] becomes [0,0,0] — the carry off the left edge is dropped. The result must be one slot longer with a leading 1.
Explore the code comparisonHide the code comparison
Missing the all-9s array growth
If you only mutate in place and return the same array, [9,9,9] becomes [0,0,0] — the carry off the left edge is dropped. The result must be one slot longer with a leading 1.
Don't write this
for i in range(len(digits) - 1, -1, -1):
if digits[i] < 9:
digits[i] += 1
return digits
digits[i] = 0
return digits # WRONG: [9,9,9] → [0,0,0]Write this instead
for i in range(len(digits) - 1, -1, -1):
if digits[i] < 9:
digits[i] += 1
return digits
digits[i] = 0
return [1] + digits # prepend the leading 1Revise
Carry the pattern into the interview
Pattern to remember
Grade-school addition with carry, scanning right-to-left
Code pattern to memorize
for i from last index down to 0:
if digits[i] < 9:
digits[i] += 1
return digits # no carry → done early
digits[i] = 0 # 9 + 1 = 10 → write 0, carry on
# fell off the left edge → was all 9s
return [1] + digits # prepend the leading 1Rules to remember
- 1Iterate from the last index toward 0 — addition carries from least-significant to most-significant, i.e. right to left.
- 2If
digits[i] < 9, increment and return immediately — a non-9 absorbs the +1 and stops any carry. - 3If
digits[i] == 9, set it to 0 and continue left; the carry keeps rippling through consecutive 9s. - 4Only the all-9s case (
999 → 1000) survives the loop — then prepend a leading 1, growing the array by one. - 5There is at most one carry to propagate (you add exactly 1), so a single pass suffices — no nested logic.
- 6Don't convert to an int and back: the input can exceed 64-bit range, so digit-by-digit is the safe approach.
Use this pattern when
- A number is represented as an array/list of digits and you must do arithmetic on it
- Big-integer addition where the value can overflow native 64-bit types
- Any 'increment with carry propagation' over a positional representation
- The +1 / +k must ripple through trailing boundary values (9s, or base-b max digits)
Choose another pattern when
- The number fits comfortably in a 32/64-bit int → just parse, add, and re-split (but rarely what's asked)
- You must add two arbitrary multi-digit arrays → that's Add Strings / Add Two Numbers, a fuller carry loop
- Digits are in least-significant-first order → reverse your iteration direction
- Non-decimal base or arbitrary increment → generalize the carry, don't hard-code 9 and 1
Interview takeaway
Plus One is the simplest carry-propagation problem: add one to a digit array and let the carry ripple through trailing 9s. The single insight — only all-9s grows the array — and the early-return-on-non-9 trick generalize directly to Add Strings, Add Two Numbers, and Add Binary. Master the right-to-left carry walk here and those become routine.
Continue
Transfer the pattern to another problem
Use a direct variation or pattern sibling to prove the idea is reusable.
Transferable patternGrade-school carry propagation over a positional digit representation. Add one from the right, ripple the carry through trailing 9s, and grow the array only when every digit is 9. The same right-to-left carry loop powers Add Binary, Add Strings, and Add Two Numbers.
Practice queueDirect variations and pattern siblings
Direct follow-ups
- Add BinaryComing soonSame right-to-left carry, but base 2 and two operands — carry when the column sum ≥ 2.
- Add StringsComing soonAdd two digit strings without parsing — the general carry loop Plus One is a special case of.
- Add Two NumbersComing soonDigits in a linked list, least-significant first — carry walks forward through the list.
- Plus One Linked ListComing soonSame +1 carry, but on a linked list — reverse, add, reverse back, or use recursion to carry from the tail.