题目描述
给定两个以字符串形式表示的非负整数 num1 和 num2。
返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
示例 1:
输入: num1 = "2", num2 = "3"
输出: "6"
示例 2:
输入: num1 = "123", num2 = "456"
输出: "56088"
说明:
num1 和 num2 的长度小于110。
num1 和 num2 只包含数字 0-9。
num1 和 num2 均不以零开头,除非是数字 0 本身。
不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。
朴素解法
本质上是道模拟题,模拟手算乘法的过程。
想要做出这道题,需要知道一个数学定理:
两个长度分别为 n 和 m 的数相乘,长度不会超过 n + m。
因此我们可以创建一个长度为 n + m 的数组 res 存储结果。
另外,最后拼接结果时需要注意忽略前导零。
代码:
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';
int 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
if (sb.length() == 0 && res[i] == 0) continue;
sb.append(res[i]);
}
return sb.length() == 0 ? "0" : sb.toString();
}
}
时间复杂度:使用
n 和
m 分别代表两个数的长度。复杂度为
。
空间复杂度:使用了长度为
m + n 的数组存储结果。复杂度为
。
总结
对于「模拟运算」类型的题目属于比较常见的题目,因为它对于一个人的算法功底要求不高,更多的是考察编码能力。
考察你是否能够很快的将一个想法/逻辑通过代码实现出来。
之前我们也做过模拟手算加法的题目,而且还是结合链表的:2. 两数相加(中等)。你还记得吗?
建议定期随机回顾以前曾经做过的题目 ~
最后
这是我们「刷穿 LeetCode」系列文章的第 No.43 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先将所有不带锁的题目刷完。
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
由于 LeetCode 的题目随着周赛 & 双周赛不断增加,为了方便我们统计进度,我们将按照系列起始时的总题数作为分母,完成的题目作为分子,进行进度计算。当前进度为 43/1916 。
为了方便各位同学能够电脑上进行调试和提交代码,我在 Github 建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode。
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和一些其他的优选题解。
关注公众号,和三叶一起刷穿 LeetCode ~