204 lines
8.2 KiB
YAML
204 lines
8.2 KiB
YAML
title: Add to Array-Form of Integer
|
||
slug: add-to-array-form-of-integer
|
||
difficulty: easy
|
||
leetcode_id: 989
|
||
leetcode_url: https://leetcode.com/problems/add-to-array-form-of-integer/
|
||
categories:
|
||
- arrays
|
||
- math
|
||
patterns:
|
||
- two-pointers
|
||
|
||
function_signature: "def add_to_array_form(num: list[int], k: int) -> list[int]:"
|
||
|
||
test_cases:
|
||
visible:
|
||
- input: { num: [1, 2, 0, 0], k: 34 }
|
||
expected: [1, 2, 3, 4]
|
||
- input: { num: [2, 7, 4], k: 181 }
|
||
expected: [4, 5, 5]
|
||
- input: { num: [2, 1, 5], k: 806 }
|
||
expected: [1, 0, 2, 1]
|
||
hidden:
|
||
- input: { num: [0], k: 1 }
|
||
expected: [1]
|
||
- input: { num: [9, 9, 9], k: 1 }
|
||
expected: [1, 0, 0, 0]
|
||
- input: { num: [1], k: 99 }
|
||
expected: [1, 0, 0]
|
||
- input: { num: [0], k: 10000 }
|
||
expected: [1, 0, 0, 0, 0]
|
||
- input: { num: [5, 5, 5], k: 555 }
|
||
expected: [1, 1, 1, 0]
|
||
|
||
description: |
|
||
The **array-form** of an integer `num` is an array representing its digits in left to right order.
|
||
|
||
- For example, for `num = 1321`, the array form is `[1,3,2,1]`.
|
||
|
||
Given `num`, the **array-form** of an integer, and an integer `k`, return *the **array-form** of the integer* `num + k`.
|
||
|
||
constraints: |
|
||
- `1 <= num.length <= 10^4`
|
||
- `0 <= num[i] <= 9`
|
||
- `num` does not contain any leading zeros except for the zero itself.
|
||
- `1 <= k <= 10^4`
|
||
|
||
examples:
|
||
- input: "num = [1,2,0,0], k = 34"
|
||
output: "[1,2,3,4]"
|
||
explanation: "1200 + 34 = 1234"
|
||
- input: "num = [2,7,4], k = 181"
|
||
output: "[4,5,5]"
|
||
explanation: "274 + 181 = 455"
|
||
- input: "num = [2,1,5], k = 806"
|
||
output: "[1,0,2,1]"
|
||
explanation: "215 + 806 = 1021"
|
||
|
||
explanation:
|
||
intuition: |
|
||
Think of this problem like performing **grade-school addition by hand**. When you add two numbers on paper, you start from the rightmost digits, add them together, carry over any excess to the next column, and work your way left.
|
||
|
||
The twist here is that one number is given as an array of digits (`num`), while the other is a regular integer (`k`). But we can treat `k` the same way — extracting its digits one at a time using modulo and division operations.
|
||
|
||
Imagine you're adding `[1,2,0,0]` (which represents 1200) and `34`:
|
||
|
||
```
|
||
1 2 0 0
|
||
+ 3 4
|
||
-----------
|
||
1 2 3 4
|
||
```
|
||
|
||
Starting from the right: `0 + 4 = 4`, then `0 + 3 = 3`, and the remaining digits carry through unchanged. The key insight is that we process both numbers from right to left, handling carries as we go, and `k` naturally shrinks as we extract its digits.
|
||
|
||
approach: |
|
||
We solve this using a **Right-to-Left Addition with Carry** approach:
|
||
|
||
**Step 1: Set up the iteration**
|
||
|
||
- Start from the rightmost digit of `num` (index `len(num) - 1`)
|
||
- Use `k` itself to hold both the number to add and the carry value
|
||
|
||
|
||
|
||
**Step 2: Process digits from right to left**
|
||
|
||
- For each position from right to left:
|
||
- If we still have digits in `num`, add the current digit to `k`
|
||
- The rightmost digit of `k` (obtained via `k % 10`) becomes the result digit
|
||
- The remaining digits of `k` (obtained via `k // 10`) become the new carry
|
||
- Insert each result digit at the front of our answer
|
||
|
||
|
||
|
||
**Step 3: Handle remaining carry**
|
||
|
||
- If `k > 0` after processing all digits of `num`, continue extracting digits from `k`
|
||
- This handles cases where the sum has more digits than the original number (e.g., `215 + 806 = 1021`)
|
||
|
||
|
||
|
||
**Step 4: Return the result**
|
||
|
||
- The result array contains the digits in the correct left-to-right order
|
||
|
||
|
||
|
||
This approach elegantly treats `k` as both the addend and the running carry, simplifying the logic.
|
||
|
||
common_pitfalls:
|
||
- title: Converting to Integer First
|
||
description: |
|
||
A tempting approach is to convert `num` to an integer, add `k`, then convert back to an array:
|
||
|
||
```python
|
||
n = int(''.join(map(str, num)))
|
||
return [int(d) for d in str(n + k)]
|
||
```
|
||
|
||
While this works for small inputs, it fails when `num` has up to `10^4` digits. Such a number far exceeds the range of standard integer types in most languages (though Python handles arbitrary precision, this approach is still inefficient and not the intended solution).
|
||
wrong_approach: "Convert array to integer, add, convert back"
|
||
correct_approach: "Simulate digit-by-digit addition with carry"
|
||
|
||
- title: Forgetting to Handle Extra Digits from k
|
||
description: |
|
||
When `k` is larger than you'd expect for the number of digits being processed, the carry can extend beyond the original array length.
|
||
|
||
For example, `num = [2,1,5]` and `k = 806`: after processing all three digits, we still have a carry that produces the leading `1` in `1021`.
|
||
|
||
Always continue the loop while `k > 0`, not just while there are digits in `num`.
|
||
wrong_approach: "Only loop through num's length"
|
||
correct_approach: "Continue while k > 0 or digits remain"
|
||
|
||
- title: Building Result in Wrong Order
|
||
description: |
|
||
Since we process digits right-to-left but need the result left-to-right, you must either:
|
||
- Insert at the front of a list (less efficient in some languages)
|
||
- Append to the end and reverse at the end (more efficient)
|
||
|
||
Appending without reversing gives digits in the wrong order.
|
||
wrong_approach: "Append digits and forget to reverse"
|
||
correct_approach: "Append and reverse, or insert at front"
|
||
|
||
key_takeaways:
|
||
- "**Digit-by-digit simulation**: Many problems involving large numbers represented as arrays require simulating arithmetic operations digit by digit"
|
||
- "**Use modulo for extraction**: `k % 10` extracts the last digit, `k // 10` removes it — a pattern useful for any digit manipulation"
|
||
- "**Carry propagation**: The carry can extend beyond the original number's length; always handle this case"
|
||
- "**Related problems**: This pattern applies to Add Two Numbers (linked lists), Multiply Strings, and Plus One"
|
||
|
||
time_complexity: "O(max(n, log k)). We process each digit of `num` once and each digit of `k` once, where `n` is the length of `num` and `k` has `log₁₀(k)` digits."
|
||
space_complexity: "O(max(n, log k)). The result array can have at most one more digit than the larger of the two inputs."
|
||
|
||
solutions:
|
||
- approach_name: Right-to-Left Addition
|
||
is_optimal: true
|
||
code: |
|
||
def add_to_array_form(num: list[int], k: int) -> list[int]:
|
||
result = []
|
||
i = len(num) - 1 # Start from rightmost digit
|
||
|
||
# Process while there are digits in num OR carry remains in k
|
||
while i >= 0 or k > 0:
|
||
if i >= 0:
|
||
k += num[i] # Add current digit to k
|
||
i -= 1
|
||
|
||
# k % 10 gives the digit for this position
|
||
# k // 10 gives the carry for next position
|
||
result.append(k % 10)
|
||
k //= 10
|
||
|
||
# We built the result right-to-left, so reverse it
|
||
return result[::-1]
|
||
explanation: |
|
||
**Time Complexity:** O(max(n, log k)) — We iterate through all digits of `num` and all digits of `k`.
|
||
|
||
**Space Complexity:** O(max(n, log k)) — The result array stores the sum.
|
||
|
||
The key insight is using `k` to hold both the number to add and the running carry. At each step, we add the current digit from `num` to `k`, extract the rightmost digit as our result, and let the remaining value carry forward.
|
||
|
||
- approach_name: Append to Front (Alternative)
|
||
is_optimal: false
|
||
code: |
|
||
def add_to_array_form(num: list[int], k: int) -> list[int]:
|
||
result = []
|
||
i = len(num) - 1
|
||
|
||
while i >= 0 or k > 0:
|
||
if i >= 0:
|
||
k += num[i]
|
||
i -= 1
|
||
|
||
# Insert at front instead of appending and reversing
|
||
result.insert(0, k % 10)
|
||
k //= 10
|
||
|
||
return result
|
||
explanation: |
|
||
**Time Complexity:** O(n × max(n, log k)) — Each `insert(0, ...)` operation is O(n) for a list.
|
||
|
||
**Space Complexity:** O(max(n, log k)) — Same result array.
|
||
|
||
This variant inserts at the front to avoid the final reverse. However, list insertions at index 0 are O(n) operations, making this less efficient for large inputs. The append-and-reverse approach is preferred in Python.
|