LC 43. 字符串相乘

题目描述

这是 LeetCode 上的 43. 字符串相乘 ,难度为 中等

给定两个以字符串形式表示的非负整数 num1num2,返回 num1num2 的乘积,它们的乘积也表示为字符串形式。

示例 1:

1
2
3
输入: num1 = "2", num2 = "3"

输出: "6"

示例 2:
1
2
3
输入: num1 = "123", num2 = "456"

输出: "56088"

说明:

  • num1num2 的长度小于 $110$。
  • num1num2 只包含数字 0-9
  • num1num2 均不以零开头,除非是数字 0 本身。
  • 不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。

模拟

本质上是道模拟题,模拟手算乘法的过程。

想要做出这道题,需要知道一个数学定理:

两个长度分别为 nm 的数相乘,长度不会超过 n + m

因此我们可以创建一个长度为 n + m 的数组 res 存储结果。

另外,最后拼接结果时需要注意忽略前导零。

Java 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public String multiply(String n1, String n2) {
int n = n1.length(), m = n2.length();
int[] res = new int[n + m];
for (int i = n - 1; i >= 0; i--) {
for (int j = m - 1; j >= 0; j--) {
int a = n1.charAt(i) - '0', b = n2.charAt(j) - '0';
int r = a * b;
r += res[i + j + 1];
res[i + j + 1] = r % 10;
res[i + j] += r / 10;
}
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n + m; i++) {
if (sb.length() == 0 && res[i] == 0) continue;
sb.append(res[i]);
}
return sb.length() == 0 ? "0" : sb.toString();
}
}

C++ 代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public:
string multiply(string num1, string num2) {
int n = num1.length(), m = num2.length();
vector<int> res(n + m, 0);
for (int i = n - 1; i >= 0; i--) {
for (int j = m - 1; j >= 0; j--) {
int a = num1[i] - '0', b = num2[j] - '0';
int r = a * b;
r += res[i + j + 1];
res[i + j + 1] = r % 10;
res[i + j] += r / 10;
}
}
string result;
for (int i = 0; i < n + m; i++) {
if (result.empty() && res[i] == 0) continue;
result.push_back(res[i] + '0');
}
return result.empty() ? "0" : result;
}
};

Python 代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution:
def multiply(self, num1: str, num2: str) -> str:
n, m = len(num1), len(num2)
res = [0] * (n + m)
for i in range(n - 1, -1, -1):
for j in range(m - 1, -1, -1):
a, b = int(num1[i]), int(num2[j])
r = a * b
r += res[i + j + 1]
res[i + j + 1] = r % 10
res[i + j] += r // 10
result = ''.join(str(x) for x in res).lstrip('0')
return result if result else '0'

TypeScript 代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function multiply(num1: string, num2: string): string {
const n = num1.length, m = num2.length;
const res = new Array(n + m).fill(0);
for (let i = n - 1; i >= 0; i--) {
for (let j = m - 1; j >= 0; j--) {
const a = parseInt(num1[i]), b = parseInt(num2[j]);
let r = a * b;
r += res[i + j + 1];
res[i + j + 1] = r % 10;
res[i + j] += Math.floor(r / 10);
}
}
let result = "";
for (let i = 0; i < n + m; i++) {
if (result.length == 0 && res[i] == 0) continue;
result += res[i].toString();
}
return result.length == 0 ? "0" : result;
};

  • 时间复杂度:使用 nm 分别代表两个数的长度。复杂度为 $O(n \times m)$
  • 空间复杂度:使用了长度为 m + n 的数组存储结果。复杂度为 $O(n + m)$

最后

这是我们「刷穿 LeetCode」系列文章的第 No.43 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。

在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。

为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode

在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!