Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2, also represented as a string.
Note: You must not use any built-in BigInteger library or convert the inputs to integer directly.
Input: num1 = "2", num2 = "3"
Output: "6"
Input: num1 = "123", num2 = "456"
Output: "56088"
Input: num1 = "999", num2 = "999"
Output: "998001"
1 <= num1.length, num2.length <= 200num1 and num2 consist of digits onlynum1 and num2 do not contain any leading zero, except the number 0 itselfThis problem simulates elementary school multiplication.
Position matters! When you multiply digit at position i with digit at position j, the result contributes to positions i+j and i+j+1.
Remember how we multiply multi-digit numbers:
123
× 456
------
738 (123 × 6)
615 (123 × 5, shifted left)
492 (123 × 4, shifted left twice)
------
56088
Instead of creating intermediate arrays for each digit, we can directly calculate which positions each product contributes to!
Key Observation:
num1 has length mnum2 has length nm + n digitsnum1[i] × num2[j]:
i + j + 1i + jExample: 123 × 456
Indices: 0 1 2
num1: 1 2 3
num2: 4 5 6
Result array: [0, 0, 0, 0, 0, 0] (length 3 + 3 = 6)
Positions: 0 1 2 3 4 5
Multiply 3 (i=2) × 6 (j=2):
Product = 18
Position i+j+1 = 2+2+1 = 5
Position i+j = 2+2 = 4
result[5] += 18 % 10 = 8
result[4] += 18 / 10 = 1
Multiply 3 (i=2) × 5 (j=1):
Product = 15
Position i+j+1 = 2+1+1 = 4
Position i+j = 2+1 = 3
result[4] += 15 % 10 = 5 (was 1, now 6)
result[3] += 15 / 10 = 1
...
m + n with zerosnum1 with each digit of num2product = num1[i] × num2[j]result[i+j+1]result[i+j]Think about positions from the right (least significant):
num1[i] is at position (m-1-i) from rightnum2[j] is at position (n-1-j) from right(m-1-i) + (n-1-j) = m+n-2-i-j from righti+j+1 (ones place) and i+j (tens place)Time Complexity: O(m × n)
Space Complexity: O(m + n)
class Solution {
public String multiply(String num1, String num2) {
// Edge cases
if (num1.equals("0") || num2.equals("0")) {
return "0";
}
int m = num1.length();
int n = num2.length();
int[] result = new int[m + n];
// Multiply each digit
for (int i = m - 1; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
int digit1 = num1.charAt(i) - '0';
int digit2 = num2.charAt(j) - '0';
int product = digit1 * digit2;
// Position in result array
int pos1 = i + j;
int pos2 = i + j + 1;
// Add to existing value at pos2
int sum = product + result[pos2];
// Update positions
result[pos2] = sum % 10;
result[pos1] += sum / 10;
}
}
// Convert to string, skip leading zeros
StringBuilder sb = new StringBuilder();
for (int num : result) {
if (!(sb.length() == 0 && num == 0)) {
sb.append(num);
}
}
return sb.length() == 0 ? "0" : sb.toString();
}
}
def multiply(num1: str, num2: str) -> str:
# Edge cases
if num1 == "0" or num2 == "0":
return "0"
m, n = len(num1), len(num2)
result = [0] * (m + n)
# Multiply each digit
for i in range(m - 1, -1, -1):
for j in range(n - 1, -1, -1):
digit1 = int(num1[i])
digit2 = int(num2[j])
product = digit1 * digit2
# Positions in result
pos1 = i + j
pos2 = i + j + 1
# Add to existing value
total = product + result[pos2]
# Update positions
result[pos2] = total % 10
result[pos1] += total // 10
# Convert to string, skip leading zeros
result_str = ''.join(map(str, result))
return result_str.lstrip('0') or '0'
Step-by-step multiplication:
num1 = "123" (indices 0,1,2)
num2 = "456" (indices 0,1,2)
result = [0,0,0,0,0,0] (indices 0-5)
i=2, j=2: 3×6=18 → result[5]+=8, result[4]+=1 → [0,0,0,0,1,8]
i=2, j=1: 3×5=15 → result[4]+=5, result[3]+=1 → [0,0,0,1,6,8]
i=2, j=0: 3×4=12 → result[3]+=2, result[2]+=1 → [0,0,1,3,6,8]
i=1, j=2: 2×6=12 → result[4]+=2, result[3]+=1 → [0,0,1,4,8,8]
i=1, j=1: 2×5=10 → result[3]+=0, result[2]+=1 → [0,0,2,4,8,8]
i=1, j=0: 2×4=8 → result[2]+=8, result[1]+=0 → [0,0,10,4,8,8]
(carry) → result[2]=0, result[1]+=1 → [0,1,0,4,8,8]
i=0, j=2: 1×6=6 → result[3]+=6, result[2]+=0 → [0,1,0,10,8,8]
(carry) → result[3]=0, result[2]+=1 → [0,1,1,0,8,8]
i=0, j=1: 1×5=5 → result[2]+=5, result[1]+=0 → [0,1,6,0,8,8]
i=0, j=0: 1×4=4 → result[1]+=4, result[0]+=0 → [0,5,6,0,8,8]
Result: "56088"
Input: num1 = "0", num2 = "9999"
Output: "0"
Must handle early!
Input: num1 = "9", num2 = "9"
Output: "81"
Input: num1 = "999999999", num2 = "999999999"
Output: "999999998000000001"
This is why we can't use int/long!
Input: num1 = "12", num2 = "9999"
Output: "119988"
This problem demonstrates:
Integer.parseInt() or similar - violates constraints for large numbersi+j and i+j+1Q: Can you optimize below O(m×n)?
Q: What if inputs are in different bases?
Q: How to handle negative numbers?
Q: What about very large numbers (millions of digits)?
| Operation | Time | Carry Direction | Complexity | |-----------|------|-----------------|------------| | Add Strings | O(max(m,n)) | Right to left | Simpler | | Multiply Strings | O(m×n) | Right to left | More complex |
Tests understanding of:
This is a fundamental problem for implementing arbitrary-precision arithmetic!