[1, 2, 9]
digits
A number is stored as an array of digits; add 1 to it. The key insight is handling carry propagation: scan right to left, increment if the digit is under 9, otherwise set it to 0 and continue. The only tricky case — all 9s — resolves in one line.
Given a non-empty array of digits representing a non-negative integer — most-significant digit first, no leading zeros — return the array after adding 1. For example: [1, 2, 9] → [1, 3, 0] (the 9 carries into the 2). The tricky edge case: [9, 9, 9] → [1, 0, 0, 0] — the result has one more digit.
< 9, increment it and return — carry is absorbed. If all digits are 9, every digit becomes 0 and you prepend a 1. No integer conversion needed; work directly on the array.digits.length - 1 and move left; we add 1 to the least-significant position first, exactly as we would on paper.[1, ...digits] (spread into a new array).return digits would give the wrong answer. Always have the return [1, ...digits] guard after the loop, not inside it.Both are O(n) worst-case, but the in-place walk exits early and uses no extra space except in the all-9s edge case (where a new array is unavoidable). The BigInt path is rarely acceptable in interviews.
[1, 2, 9]. We add 1 from the rightmost digit, propagating carry left.1▶function plusOne(digits: number[]): number[] {2▶ for (let i = digits.length - 1; i >= 0; i--) {3 if (digits[i] < 9) {4 digits[i]++; // no carry — we're done5 return digits;6 }7 digits[i] = 0; // digit was 9: write 0, carry continues8 }9 // All digits were 9 (e.g. [9,9,9] → [1,0,0,0])10 return [1, ...digits];11}
function plusOne(digits: number[]): number[] {
for (let i = digits.length - 1; i >= 0; i--) {
if (digits[i] < 9) {
digits[i]++; // no carry — we're done
return digits;
}
digits[i] = 0; // digit was 9: write 0, carry continues
}
// All digits were 9 (e.g. [9,9,9] → [1,0,0,0])
return [1, ...digits];
}< 9, a simple increment absorbs the carry and we return immediately — no further work needed. This is the common case.[9,9,9] → [0,0,0]). Prepending a 1 gives the correct result [1,0,0,0]. The spread syntax creates a new array; mutating digits in-place is fine for the 0s but we need one extra slot.digits = [...digits] before the loop. Same O(n) time, O(n) space.k and change the loop to sum = digits[i] + carry; digits[i] = sum % 10; carry = Math.floor(sum / 10). This is exactly the Add Strings / Add Two Numbers pattern.BigInt, add 1, stringify, split. Works but is O(n) allocation-heavy and fails for very large arrays in JS without BigInt.| "increment a number stored as digit array" | right-to-left carry walk |
| a 9 in the ones (or tens, hundreds) place | set to 0, propagate carry |
| all digits are 9 | prepend 1 after the loop |
| "add two numbers / add binary" | same carry loop, two sources |
function plusOne(digits: number[]): number[] {
for (let i = digits.length - 1; i >= 0; i--) {
if (digits[i] < 9) {
digits[i]++;
return digits;
}
digits[i] = 0;
}
return [1, ...digits];
}[1, 2, 9] return?[9, 9, 9] return?return [1, ...digits] correct rather than digits.unshift(1); return digits?[2, 9, 9]: how many iterations does the loop execute?