Multiply Strings
Schoolbook product into an int array — position i*j contributes to slots i+j and i+j+1; final carry-resolution sweep.
4 min read
math string
Problem#
Multiply two non-negative big integers given as strings; return the product as a string. No BigInteger libraries.
Examples#
"2", "3"→"6"."123", "456"→"56088".
Constraints#
1 <= length <= 200.
Approach#
Result has at most m + n digits. For each (i, j), the product a[i] * b[j] contributes to positions i + j (tens) and i + j + 1 (units) of the result array. After accumulating, do a final carry-propagation sweep.
Solution#
class Solution {public: string multiply(string a, string b) { if (a == "0" || b == "0") return "0"; int m = a.size(), n = b.size(); vector<int> r(m + n, 0); for (int i = m - 1; i >= 0; --i) for (int j = n - 1; j >= 0; --j) { int p = (a[i] - '0') * (b[j] - '0'); int sum = p + r[i + j + 1]; r[i + j + 1] = sum % 10; r[i + j] += sum / 10; } string out; for (int d : r) { if (!out.empty() || d != 0) out.push_back('0' + d); } return out; }};func multiply(a string, b string) string { if a == "0" || b == "0" { return "0" } m, n := len(a), len(b) r := make([]int, m+n) for i := m - 1; i >= 0; i-- { for j := n - 1; j >= 0; j-- { p := int(a[i]-'0') * int(b[j]-'0') sum := p + r[i+j+1] r[i+j+1] = sum % 10 r[i+j] += sum / 10 } } out := []byte{} for _, d := range r { if len(out) > 0 || d != 0 { out = append(out, byte('0'+d)) } } return string(out)}class Solution: def multiply(self, a: str, b: str) -> str: if a == "0" or b == "0": return "0" m, n = len(a), len(b) r = [0] * (m + n) for i in range(m - 1, -1, -1): for j in range(n - 1, -1, -1): p = (ord(a[i]) - ord('0')) * (ord(b[j]) - ord('0')) total = p + r[i + j + 1] r[i + j + 1] = total % 10 r[i + j] += total // 10 out = [] for d in r: if out or d != 0: out.append(chr(ord('0') + d)) return "".join(out)function multiply(a, b) { if (a === "0" || b === "0") return "0"; const m = a.length, n = b.length; const r = new Array(m + n).fill(0); for (let i = m - 1; i >= 0; i--) { for (let j = n - 1; j >= 0; j--) { const p = (a.charCodeAt(i) - 48) * (b.charCodeAt(j) - 48); const sum = p + r[i + j + 1]; r[i + j + 1] = sum % 10; r[i + j] += Math.floor(sum / 10); } } let out = ""; for (const d of r) { if (out.length > 0 || d !== 0) out += d; } return out;}class Solution { public String multiply(String a, String b) { if (a.equals("0") || b.equals("0")) return "0"; int m = a.length(), n = b.length(); int[] r = new int[m + n]; for (int i = m - 1; i >= 0; i--) { for (int j = n - 1; j >= 0; j--) { int p = (a.charAt(i) - '0') * (b.charAt(j) - '0'); int sum = p + r[i + j + 1]; r[i + j + 1] = sum % 10; r[i + j] += sum / 10; } } StringBuilder out = new StringBuilder(); for (int d : r) { if (out.length() > 0 || d != 0) out.append((char) ('0' + d)); } return out.toString(); }}function multiply(a: string, b: string): string { if (a === "0" || b === "0") return "0"; const m = a.length, n = b.length; const r: number[] = new Array(m + n).fill(0); for (let i = m - 1; i >= 0; i--) { for (let j = n - 1; j >= 0; j--) { const p = (a.charCodeAt(i) - 48) * (b.charCodeAt(j) - 48); const sum = p + r[i + j + 1]; r[i + j + 1] = sum % 10; r[i + j] += Math.floor(sum / 10); } } let out = ""; for (const d of r) { if (out.length > 0 || d !== 0) out += d; } return out;}Editorial#
The (i+j, i+j+1) trick is what makes this elegant — there’s no separate “shift by powers of 10” step. Each pair of multiplications correctly accumulates with carry handled in one pass. Skipping leading zeros at the end gives the canonical form.
Complexity#
- Time:
O(m * n). - Space:
O(m + n).
Concept revision#
Related#