题目描述
这是 LeetCode 上的 43. 字符串相乘 ,难度为 中等。
Tag : 「数学」、「模拟」
给定两个以字符串形式表示的非负整数 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 < n + m; i++) { if (sb.length() == 0 && res[i] == 0) continue; sb.append(res[i]); } return sb.length() == 0 ? "0" : sb.toString(); } } 复制代码
- 时间复杂度:使用
n
和m
分别代表两个数的长度。复杂度为 O(n∗m)O(n * m)O(n∗m) - 空间复杂度:使用了长度为
m + n
的数组存储结果。复杂度为 O(n+m)O(n + m)O(n+m)
最后
这是我们「刷穿 LeetCode」系列文章的第 No.43
篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先将所有不带锁的题目刷完。
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:github.com/SharingSour…
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。