题目描述
给定两个以字符串形式表示的非负整数 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)或直接将输入转换为整数来处理。
竖式乘法
第一种方式比较简单,我们只要回想起我们平时计算乘法的方法。如果 num1 和 num2 之一是 0,则直接返回 0 即可。如果 num1 和 num2 都不是 0,则可以通过模拟「竖式乘法」的方法计算乘积。从右往左遍历乘数,将乘数的每一位与被乘数相乘得到对应的结果,再将每次得到的结果累加。需要注意的是,num2 除了最低位以外,其余的每一位的运算结果都需要补 0。
关于字符串相加的代码,可以参考:字符串相加 | 笑话人生
1 | public String multiply(String num1, String num2) { |
复杂度分析
- 时间复杂度:O(mn + n²),其中 m 和 n 分别是 num1 和 num2 的长度。需要从右往左遍历 num2,对于 num2 的每一位,都要和 num1 的每一位计算乘积,因此计算乘积的总数是 mn,字符串相加操作共有 n 次,相加的字符串长度最长为
m + n
,因此字符串相加的时间复杂度是O(mn + n²)。总时间复杂度是O(mn + n²)。 - 空间复杂度:O(m + n),其中 m 和 n 分别是 num1 和 num2 的长度。空间复杂度取决于存储中间状态的字符串,由于乘积的最大长度为
m + n
,因此存储中间状态的字符串的长度不会超过m + n
。
直接做乘积
上一个方法从右往左遍历乘数,将乘数的每一位与被乘数相乘得到对应的结果,再将每次得到的结果累加,整个过程中涉及到较多字符串相加的操作。如果使用数组代替字符串存储结果,则可以减少对字符串的操作。令 m 和 n 分别表示 num1 和 num2 的长度,并且它们均不为 0,则 num1 和 num2 的乘积的长度为 m + n - 1
或 m + n
。
由于 num1 和 num2 的乘积的最大长度为 m + n
,因此创建长度为 m + n
的数组 ansArr 用于存储乘积。对于任意 0 ≤ i < m
和 0 ≤ j < n
,num1[i] × num2[j]
的结果位于 ansArr[i + j + 1]
,如果 ansArr[i + j + 1] ≥ 10
,则将进位部分加到ansArr[i + j]
。最后,将数组 ansArr 转成字符串,如果最高位是 0 则舍弃最高位。
1 | public String multiply(String num1, String num2) { |
复杂度分析
- 时间复杂度:O(mn),其中 m 和 n 分别是 num1 和 num2 的长度。需要计算 num1 的每一位和 num2 的每一位的乘积。
- 空间复杂度:O(m + n),其中 m 和 n 分别是 num1 和 num2 的长度。需要创建一个长度为
m + n
的数组存储乘积。
来源
文章标题:字符串相乘
文章作者:cylong
文章链接:https://0skyu.cn/posts/b1e8.html
有问题或者建议欢迎在下方评论。欢迎转载、引用,但希望标明出处,感激不尽(●’◡’●)
- 本文标题:字符串相乘
- 创建时间:2020-08-13 02:32:04
- 本文链接:posts/b1e8.html
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!