LC 43. 字符串相乘
题目描述
这是 LeetCode 上的 43. 字符串相乘 ,难度为 中等。
给定两个以字符串形式表示的非负整数 num1
和 num2
,返回 num1
和 num2
的乘积,它们的乘积也表示为字符串形式。
示例 1:1
2
3输入: num1 = "2", num2 = "3"
输出: "6"
示例 2:1
2
3输入: num1 = "123", num2 = "456"
输出: "56088"
说明:
num1
和num2
的长度小于 $110$。num1
和num2
只包含数字0-9
。num1
和num2
均不以零开头,除非是数字0
本身。- 不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。
模拟
本质上是道模拟题,模拟手算乘法的过程。
想要做出这道题,需要知道一个数学定理:
两个长度分别为 n
和 m
的数相乘,长度不会超过 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
21class 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
22class 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
13class 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
19function 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;
};
- 时间复杂度:使用
n
和m
分别代表两个数的长度。复杂度为 $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 协议 ,转载请注明出处!