Problem Walkthrough

Plus One LeetCode 66 — Complete Guide

Master LeetCode 66 Plus One by propagating carry right-to-left through a digit array, handling the elegant all-9s edge case where every digit becomes 0 and a new leading 1 must be prepended, growing the array by exactly one element.

7 min read|

Plus One

LeetCode 66

Problem Overview — Increment a Large Integer Stored as a Digit Array

LeetCode 66 Plus One gives you a large integer represented as an array of digits, where digits[0] is the most significant digit and digits[n-1] is the least significant digit. Your task: increment the integer by one and return the resulting digit array. The array never has leading zeros (except the number 0 itself, represented as [0]).

This is a straightforward simulation of how you add 1 by hand: start at the rightmost digit, add 1, and handle any carry that propagates left. The challenge is purely in the carry logic and the one edge case where carry propagates all the way past the leftmost digit — when every digit in the array is 9.

Despite its simplicity, Plus One tests your ability to simulate arithmetic correctly and handle boundary conditions cleanly. It is a foundational problem in the digit array family, alongside problems like Multiply Strings and Add Binary, and demonstrates that you can avoid integer overflow by operating digit by digit.

  • 1 ≤ digits.length ≤ 100
  • 0 ≤ digits[i] ≤ 9
  • digits does not contain any leading zeros
  • Most significant digit is stored first (digits[0])
  • Return the incremented digit array

Simple Case — Last Digit Less Than 9, No Carry Needed

The overwhelmingly common case is that the last digit is not 9. When digits[n-1] < 9, simply increment it by 1 and return the array immediately. No carry occurs, no other digits change, and the array length stays the same. This single-line operation handles inputs like [1,2,3] → [1,2,4] and [9,8,7] → [9,8,8] without touching the rest of the array.

Even when the input has internal 9s — say [1,9,9] — the last digit rule still applies: if digits[n-1] < 9, return immediately. Only when the last digit is exactly 9 does carry become relevant. In practice, for random inputs, over 90% of increments terminate at the last digit, making this early-exit pattern both correct and performant.

The iteration strategy is to loop from the last index backward toward index 0, applying this logic at each position: if the current digit is less than 9, increment it and return. This backward loop naturally encodes the carry mechanic without any explicit carry variable — the loop itself is the carry propagation engine.

💡

Iterate from the Last Digit Backward — Return on the First Non-9

Iterate from the last digit backward. At each position, if the digit is less than 9, increment it and return the array immediately — no carry needed. Only continue the loop if the digit was 9 (set it to 0 and carry left). This pattern eliminates the need for an explicit carry variable and makes the common case a single-pass early exit.

Carry Propagation — When a 9 Becomes 0 and the Carry Moves Left

When the current digit is 9, adding 1 produces 10: the digit becomes 0 and a carry of 1 propagates to the next position to the left. Set digits[i] = 0 and continue the loop to the next iteration at index i-1. This precisely mirrors hand arithmetic: 9 + 1 = 10, write 0, carry 1.

Carry can chain through multiple consecutive 9s. Consider [1,2,9,9]: start at index 3 (digit 9), set to 0, carry left. Index 2 is also 9, set to 0, carry left. Index 1 is 2, which is less than 9 — increment to 3 and return [1,3,0,0]. The carry consumed both trailing 9s and absorbed into the first non-9 digit encountered.

The loop terminates as soon as it finds a digit less than 9. If the entire array is 9s, the loop runs through all indices setting each to 0, and exits the loop without ever returning early. That post-loop case is the all-9s edge case handled separately.

  1. 1Loop i from digits.length - 1 down to 0
  2. 2If digits[i] < 9: increment digits[i], return digits immediately
  3. 3If digits[i] == 9: set digits[i] = 0, continue loop (carry propagates left)
  4. 4If loop completes without returning: all digits were 9, all are now 0
  5. 5Handle the all-9s case after the loop exits

The All-9s Edge Case — [9,9,9] Becomes [1,0,0,0]

If the loop completes without triggering an early return, every digit in the array was 9. The loop has already set all of them to 0, leaving an array of all zeros. Now we need to prepend a 1 to represent the carry out of the most significant position. The result is [1, 0, 0, ..., 0] — one digit longer than the input.

For example, [9,9,9] + 1 = 1000. The loop sets all three digits to 0, yielding [0,0,0]. Then we prepend 1 to get [1,0,0,0]. Similarly [9] → [1,0], [9,9] → [1,0,0]. The new array always has exactly one more element than the input, and the first element is always 1.

This is the only case where the output array is longer than the input. All other inputs produce an array of the same length. In Python, the cleanest expression is [1] + digits (list concatenation). In Java, create a new int array of length digits.length + 1, set index 0 to 1, and leave the rest as 0 (default). Both are O(n) time and O(n) space.

ℹ️

The All-9s Case Is Elegant — The Loop Does All the Work

The all-9s case is elegant: the backward loop sets every digit to 0 as it propagates carry left. When the loop exits, the array is already all zeros — no additional work needed except prepending 1. This single edge case is what elevates a trivial problem to an interesting one. It is also the only case where the array grows in length, making it the one scenario where you cannot modify strictly in place.

In-Place vs New Array — When You Can and Cannot Modify In Place

For all inputs except the all-9s case, the algorithm modifies the input array in place and returns it. No new array allocation is needed; the output has the same length as the input. This is O(1) extra space. The early-return optimization in the simple case makes the common path extremely fast — one digit check, one increment, one return.

For the all-9s case, a new array of length n+1 must be created. You cannot extend the original array in place (at least not in Java/C++; Python lists are dynamic). In Python, [1] + digits is concise and idiomatic. In Java, int[] result = new int[digits.length + 1]; result[0] = 1; — the rest defaults to 0, which is correct since the loop already zeroed out digits (though we actually just need the new array since digits is now all zeros).

A common interview follow-up asks about space complexity. The answer is: O(1) extra space for the non-all-9s case (in-place modification), and O(n) for the all-9s case (new array). Since the all-9s case is the only one requiring new allocation, the amortized space cost is low — but worst-case space is O(n).

  1. 1For digits like [1,2,3]: modify in place, O(1) extra space
  2. 2For digits like [1,9,9]: modify in place (trailing 9s become 0, non-9 absorbs carry), O(1) extra space
  3. 3For digits like [9,9,9]: new array of length n+1 required, O(n) extra space
  4. 4Python: return [1] + digits after the loop (list concatenation creates new list)
  5. 5Java: return new int[]{1, ...zeros} or new int[digits.length + 1] with result[0] = 1

Code Walkthrough — Python and Java with O(n) Time O(1) Space

Python solution: def plusOne(digits): for i in range(len(digits) - 1, -1, -1): if digits[i] < 9: digits[i] += 1; return digits; digits[i] = 0; return [1] + digits. Eight lines including the function definition. The loop iterates from len-1 down to 0 (Python range with step -1). If a digit is less than 9, increment and return immediately. If 9, set to 0 and continue. After the loop, all digits are 0 — prepend 1.

Java solution: public int[] plusOne(int[] digits) { for (int i = digits.length - 1; i >= 0; i--) { if (digits[i] < 9) { digits[i]++; return digits; } digits[i] = 0; } int[] result = new int[digits.length + 1]; result[0] = 1; return result; } Identical logic — the loop condition i >= 0 mirrors Python's range down to 0. After the loop, allocate a new array of size n+1 and set the first element to 1.

Time complexity: O(n) worst case (all-9s input traverses the entire array). O(1) average case (terminates at the first non-9 from the right; for uniform random digits, expected position is near the end). Space complexity: O(1) for the non-all-9s case, O(n) for all-9s. Both Python and Java solutions are clean, readable, and handle all edge cases correctly.

⚠️

Do Not Convert to Integer and Back — Arrays Can Exceed Integer Range

Do not convert the digit array to an integer, add 1, then convert back to digits. The problem states digits.length can be up to 100, meaning the array can represent a number with 100 digits — far exceeding the range of any 64-bit integer (which holds only ~19 digits). The digit-by-digit approach works for arbitrarily large numbers and avoids overflow entirely. This is the core insight the problem is testing.

Ready to master algorithm patterns?

YeetCode flashcards help you build pattern recognition through active recall and spaced repetition.

Start practicing now