LeetCode #43 Medium

Multiply Strings

Given two non-negative integers represented as strings num1 and num2, return their product as a string without using any built-in big-integer multiplication.

mathstringssimulation
Open on LeetCode ↗
02

Intuition

Think about how you multiply on paper: each digit of one number multiplies each digit of the other, and the partial product lands at a specific position determined by the positions of the two digits. If digit i (from the right, 0-indexed) of num1 multiplies digit j of num2, the result contributes to positions i + j and i + j + 1 in the output. You can accumulate all these partial products into a result array and propagate carries at the end — or even as you go. The result of multiplying an m-digit number by an n-digit number has at most m + n digits.

How to spot this pattern

When a problem says 'multiply two numbers given as strings' and forbids big-integer libraries, the shape is grade-school multiplication. The key mechanical detail is the positional formula: digit i from the right times digit j from the right contributes to position i + j + 1 (and carry to i + j). The same positional thinking applies to polynomial multiplication and convolution.

03

Approach

1

Allocate a result array of length `m + n`

The product of an m-digit number and an n-digit number has at most m + n digits (e.g., 99 * 99 = 9801, 2 + 2 = 4 digits). Create an integer array of that size, initialized to zero. Each cell will accumulate partial products before carries are resolved.

2

Multiply each pair of digits and place the result at the right position

Iterate i from the end of num1 and j from the end of num2. Multiply the two digits, add to the current value at position i + j + 1 in the result array (the ones place of this partial product). Then propagate any carry to position i + j immediately: result[i + j] += result[i + j + 1] // 10 and result[i + j + 1] %= 10. Doing the carry inline keeps each cell as a single digit.

3

Convert the result array to a string, stripping leading zeros

Join the digits into a string. Strip leading zeros with lstrip('0'). If the entire result is zeros (the product is zero), return "0". Time is O(m * n) for the nested multiplication. Space is O(m + n) for the result array.

04

Solution

1class Solution:
2 def multiply(self, num1, num2):
3 m = len(num1)
4 n = len(num2)
5 result = [0] * (m + n)
6 for i in range(m - 1, -1, -1):
7 for j in range(n - 1, -1, -1):
8 prod = int(num1[i]) * int(num2[j])
9 p1 = i + j
10 p2 = i + j + 1
11 total = prod + result[p2]
12 result[p2] = total % 10
13 result[p1] += total // 10
14 s = ''.join(str(d) for d in result).lstrip('0')
15 return s if s else '0'
05

Common pitfalls

Placing the partial product at position i + j instead of i + j + 1

✗ Wrong
result[i + j] += d1 * d2
✓ Right
result[i + j + 1] += d1 * d2

Position i + j + 1 is the ones place of the partial product; position i + j is the tens (carry) place. Placing at i + j shifts every partial product one position too high, making the result 10x too large.

Iterating digits from the left instead of the right

✗ Wrong
for i in range(len(num1)):
    for j in range(len(num2)):
✓ Right
for i in range(len(num1) - 1, -1, -1):
    for j in range(len(num2) - 1, -1, -1):

The positional formula assumes i and j are counted from the right (least significant). Iterating from the left without adjusting the index maps digits to wrong positions.

Returning an empty string when the product is zero

✗ Wrong
return ''.join(str(d) for d in result).lstrip('0')
✓ Right
s = ''.join(str(d) for d in result).lstrip('0')
return s if s else '0'

lstrip('0') on "0000" produces an empty string. The product of "0" and anything is "0", not "".

06

Edge cases

One of the inputs is "0"

Every partial product is zero, so the result array is all zeros. The leading-zero strip removes everything, and we return "0".

One input is "1"

Each digit of the other number multiplies by 1 and lands in the correct position. The result is the other number itself.

Very large numbers (hundreds of digits)

The algorithm is O(m n) with no integer overflow because each cell stores at most a two-digit intermediate (99 + carry = 81 + 9 = 90) before the carry propagates.

07

Complexity

Time
O(m * n)
Space
O(m + n)
m and n are the lengths of the two input strings. The result array holds at most m + n digits.