989. Add to Array-Form of Integer
Problem Description
You are given an integer represented as an array of its digits (called the "array-form"), where each element in the array is a single digit. The digits are ordered from left to right, with the leftmost digit being the most significant.
For example, if you have the number 1321, its array-form would be [1, 3, 2, 1]
.
Your task is to add an integer k
to this array-form number and return the result also in array-form.
Input:
num
: An array of integers where each element is a digit (0-9) representing a number in array-formk
: An integer to be added to the number represented bynum
Output:
- Return an array representing the sum
num + k
in array-form
Example:
If num = [1, 3, 2, 1]
(representing 1321) and k = 34
, the output should be [1, 3, 5, 5]
(representing 1355, since 1321 + 34 = 1355).
The solution simulates the addition process digit by digit from right to left, handling carries along the way. It starts from the last digit of the array and adds k
to it. The remainder when divided by 10 becomes the current digit, and the quotient becomes the new value of k
(acting as the carry). This continues until both the array is fully processed and k
becomes 0. The result is built in reverse order and then reversed at the end to get the correct array-form representation.
Intuition
Think about how we normally add two numbers by hand. We start from the rightmost digit (the ones place) and work our way left, carrying over any value greater than 9 to the next position. This is exactly what we need to do here.
The clever insight is that instead of converting the entire array to an integer, adding k
, and then converting back to an array (which could cause overflow for very large numbers), we can treat k
itself as our running carry value.
Consider adding 34 to 1321:
1 3 2 1
+ 3 4
---------
1 3 5 5
Starting from the rightmost digit: we add 1 + 34 = 35. We keep 5 as the current digit and carry 3 (which is 35 divided by 10). Then we add 2 + 3 = 5, with no carry. This continues until we've processed all digits.
The key realization is that at each step, we can:
- Add the current digit (if it exists) to
k
- Extract the rightmost digit of this sum using
k % 10
- this becomes our current result digit - Update
k
tok // 10
- this becomes our carry for the next position
By treating k
as both the number to add AND the carry, we elegantly handle all cases:
- When
k
is initially large (like 999), it naturally propagates through multiple positions - When the array is exhausted but
k
still has value, we continue adding digits - When both are exhausted (
k = 0
and no more array digits), we're done
Building the result in reverse order (appending to the end) and then reversing at the end is more efficient than inserting at the beginning each time.
Learn more about Math patterns.
Solution Approach
The implementation follows the simulation approach, processing digits from right to left while maintaining a carry value.
Algorithm Steps:
-
Initialize variables:
- Create an empty list
ans
to store the result digits - Set pointer
i
to the last index of the array (len(num) - 1
)
- Create an empty list
-
Main loop: Continue while either we have digits to process (
i >= 0
) or there's still a carry value (k > 0
):a. Add current digit to k:
k += 0 if i < 0 else num[i]
- If we're still within the array bounds, add the current digit to
k
- If we've exhausted the array, add 0 (effectively just processing the remaining carry)
b. Extract digit and carry:
k, x = divmod(k, 10)
- Use
divmod(k, 10)
to simultaneously get:x
: The remainder (current digit to add to result)k
: The quotient (carry for the next position)
c. Store the digit:
ans.append(x)
- Append the current digit to the result list
d. Move to next position:
i -= 1
- Decrement the pointer to process the next digit from right to left
- If we're still within the array bounds, add the current digit to
-
Reverse the result:
return ans[::-1]
- Since we built the answer from least significant to most significant digit, reverse it to get the correct order
Example Walkthrough:
For num = [1, 2, 0, 0]
and k = 34
:
- Round 1:
i=3
,k=34+0=34
,divmod(34,10)=(3,4)
, append4
,k=3
- Round 2:
i=2
,k=3+0=3
,divmod(3,10)=(0,3)
, append3
,k=0
- Round 3:
i=1
,k=0+2=2
,divmod(2,10)=(0,2)
, append2
,k=0
- Round 4:
i=0
,k=0+1=1
,divmod(1,10)=(0,1)
, append1
,k=0
- Result:
[4,3,2,1]
reversed gives[1,2,3,4]
(representing 1234)
The time complexity is O(max(n, log k))
where n
is the length of the array, and space complexity is O(max(n, log k))
for the result array.
Ready to land your dream job?
Unlock your dream job with a 3-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through adding k = 56
to num = [2, 7]
(representing 27).
Initial Setup:
num = [2, 7]
,k = 56
ans = []
(empty result list)i = 1
(pointing to the last index)
Iteration 1:
- Current digit:
num[1] = 7
- Add to k:
k = 56 + 7 = 63
- Extract digit and carry:
63 ÷ 10 = 6
remainder3
- New digit:
3
- New k (carry):
6
- New digit:
- Append
3
to ans:ans = [3]
- Move pointer:
i = 0
Iteration 2:
- Current digit:
num[0] = 2
- Add to k:
k = 6 + 2 = 8
- Extract digit and carry:
8 ÷ 10 = 0
remainder8
- New digit:
8
- New k (carry):
0
- New digit:
- Append
8
to ans:ans = [3, 8]
- Move pointer:
i = -1
Iteration 3:
- Check conditions:
i = -1
(no more digits) andk = 0
(no carry) - Exit loop
Final Step:
- Reverse the result:
[3, 8]
becomes[8, 3]
- Return
[8, 3]
(representing 83)
Verification: 27 + 56 = 83 ✓
This example demonstrates how the algorithm handles digit-by-digit addition with carry propagation, building the result in reverse order for efficiency.
Solution Implementation
1class Solution:
2 def addToArrayForm(self, num: List[int], k: int) -> List[int]:
3 """
4 Add integer k to the array-form of an integer num.
5
6 Args:
7 num: Array representation of an integer (each digit is an element)
8 k: Integer to be added to num
9
10 Returns:
11 Array representation of the sum num + k
12 """
13 result = []
14 index = len(num) - 1
15
16 # Process digits from right to left, handling carry
17 while index >= 0 or k > 0:
18 # Add current digit from num array (if exists) to k
19 if index >= 0:
20 k += num[index]
21
22 # Extract the last digit and update carry
23 carry, digit = divmod(k, 10)
24 result.append(digit)
25
26 # Update k with carry value for next iteration
27 k = carry
28 index -= 1
29
30 # Reverse the result since we built it backwards
31 return result[::-1]
32
1class Solution {
2 public List<Integer> addToArrayForm(int[] num, int k) {
3 // Initialize result list to store digits of the sum
4 List<Integer> result = new ArrayList<>();
5
6 // Process digits from right to left (least significant to most significant)
7 // Continue while there are digits in num array or k still has remaining value
8 for (int index = num.length - 1; index >= 0 || k > 0; index--) {
9 // Add current digit from num array to k (if index is valid)
10 // This effectively adds the digit and any carry from previous iteration
11 if (index >= 0) {
12 k += num[index];
13 }
14
15 // Extract the least significant digit of current sum and add to result
16 result.add(k % 10);
17
18 // Keep the carry (remaining value) for next iteration
19 k /= 10;
20 }
21
22 // Reverse the result since we built it from least to most significant digit
23 Collections.reverse(result);
24
25 return result;
26 }
27}
28
1class Solution {
2public:
3 vector<int> addToArrayForm(vector<int>& num, int k) {
4 vector<int> result;
5
6 // Process digits from right to left (least significant to most significant)
7 // Continue while there are digits in num array or k still has value
8 for (int i = num.size() - 1; i >= 0 || k > 0; --i) {
9 // Add current digit from num array (if exists) to k
10 if (i >= 0) {
11 k += num[i];
12 }
13
14 // Extract the least significant digit and add to result
15 result.push_back(k % 10);
16
17 // Keep the carry for next iteration
18 k /= 10;
19 }
20
21 // Result was built in reverse order, so reverse it back
22 reverse(result.begin(), result.end());
23
24 return result;
25 }
26};
27
1/**
2 * Adds an integer k to a number represented as an array of digits
3 * @param num - Array representing a number where each element is a single digit
4 * @param k - Integer to add to the number
5 * @returns Array representing the sum of num and k
6 */
7function addToArrayForm(num: number[], k: number): number[] {
8 // Result array to store the sum digits
9 const result: number[] = [];
10
11 // Process from the least significant digit (rightmost) to most significant
12 // Continue while there are digits in num to process OR carry value k remains
13 for (let index = num.length - 1; index >= 0 || k > 0; index--) {
14 // Add current digit from num array to k (if index is valid)
15 if (index >= 0) {
16 k += num[index];
17 }
18
19 // Extract the least significant digit of current sum and add to result
20 result.push(k % 10);
21
22 // Keep the carry for next iteration by removing the least significant digit
23 k = Math.floor(k / 10);
24 }
25
26 // Since we added digits from least to most significant, reverse to get correct order
27 return result.reverse();
28}
29
Time and Space Complexity
Time Complexity: O(max(n, log k))
, where n
is the length of the array num
and log k
represents the number of digits in k
.
The while loop continues as long as either i >= 0
(iterating through the array) or k > 0
(processing remaining digits of k
). In each iteration:
- We traverse the array from right to left, which takes
O(n)
iterations - If
k
has more digits than the array length, we continue processing untilk
becomes 0, which takesO(log k)
additional iterations - Each operation inside the loop (addition, division, modulo, append) takes
O(1)
time
Therefore, the total time complexity is O(max(n, log k))
. When k
is relatively small compared to the array size, this simplifies to O(n)
as stated in the reference answer.
Space Complexity: O(1)
(excluding the output array)
The algorithm uses only a constant amount of extra space:
- Variable
i
for indexing:O(1)
- Variable
x
for storing the digit:O(1)
- Variable
k
is modified in place:O(1)
The ans
array stores the result, but since it's the required output, it's not counted in the space complexity analysis. Therefore, the auxiliary space complexity is O(1)
.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Forgetting to Handle Remaining Carry
A common mistake is only processing while there are digits in the array, forgetting that k
might still have value after all digits are processed.
Incorrect approach:
while index >= 0: # Wrong! Stops too early
k += num[index]
carry, digit = divmod(k, 10)
result.append(digit)
k = carry
index -= 1
Issue: If num = [9, 9]
and k = 1
, this would give [0, 0]
instead of [1, 0, 0]
because it doesn't process the final carry.
Solution: Always check both conditions: while index >= 0 or k > 0
2. Building Result in Wrong Order Without Reversing
Another pitfall is appending digits in the wrong order or forgetting to reverse at the end.
Incorrect approach:
result = []
for i in range(len(num)): # Processing left to right
# ... addition logic
result.append(digit)
return result # Forgot to handle proper ordering
Solution: Either:
- Build from right to left and reverse at the end (as in the correct solution)
- Or use
result.insert(0, digit)
to prepend each digit (less efficient but clearer)
3. Modifying the Input Array In-Place
Some might try to modify the input array directly, which can cause issues when the result has more digits than the input.
Incorrect approach:
for i in range(len(num) - 1, -1, -1):
num[i] += k
k, num[i] = divmod(num[i], 10)
# What if k > 0 here? Can't extend num properly
Issue: When num = [9]
and k = 99
, the result should be [1, 0, 8]
, but you can't easily extend the input array.
Solution: Always create a new result array to handle size changes gracefully.
4. Integer Overflow in Other Languages
While Python handles arbitrary precision integers, in languages like Java or C++, converting the entire array to an integer could cause overflow.
Incorrect approach (in concept):
# This works in Python but would fail in other languages for large arrays
number = int(''.join(map(str, num)))
result_num = number + k
return [int(d) for d in str(result_num)]
Solution: Stick to the digit-by-digit simulation approach which works regardless of the number size.
Which of the two traversal algorithms (BFS and DFS) can be used to find whether two nodes are connected?
Recommended Readings
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!