题目:字符串相乘
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
注意: 不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
示例 1:
输入: num1 = "2", num2 = "3"
输出: "6"
示例 2:
输入: num1 = "123", num2 = "456"
输出: "56088"
提示:
1 <= num1.length, num2.length <= 200num1和num2只能由数字组成。num1和num2都不包含任何前导零,除了数字0本身。
解题思路
使用数组储存得到的各位置乘积。一开始完全使用字符串处理,可以过但是速度比较慢,使用数组处理速度是完全用字符串处理的1/8左右。
字符串相乘或者相加其实都是差不多的,无非就是模拟我们做竖式的运算。在做竖式a*b的时候,我们一般分为两个步骤,首先,将b中的每一位,分别和a做乘法运算,然后再将乘法的结果加起来。
1.先筛选出最短的字符串和最长的,最短的当做乘数,最长的当做被乘数 2.创建一个StringBuffer数组,StringBuffer[i]表示被乘数和乘数的第i位的乘积,注意点:随着乘数的位数越高,对应的乘积的位数也应该越高。例如123 * 20,第一位0 和123相乘,结果为000,第二位2和123相乘,结果应该为2460,我们要把位数带上。 3.最后再把这些结果都相加 4.程序中是把数倒着计算的,sb[i]的i越小,表示乘数的位数越大。
代码实现
public String multiply(String num1, String num2) {
if (num1.equals("0") || num2.equals("0")) return "0";
char[] s1 = num1.toCharArray();
char[] s2 = num2.toCharArray();
int M = s1.length, N = s2.length;
int[] res = new int[M + N];
// 从右往左计算对角线累加和,并计算进位
for (int i = M - 1; i >= 0; i--) {
for (int j = N - 1; j >= 0; j--) {
int k = i + j + 1; // 第k条对角线
int sum = (s1[i] - '0') * (s2[j] - '0') + res[k]; // a*b + 进位
res[k] = sum % 10; // 当前存个位
res[k - 1] += sum / 10; // 进位应该加到左边一位上
}
}
StringBuilder sb = new StringBuilder();
for (int i = res[0] != 0 ? 0 : 1; i < res.length; i++) sb.append(res[i]);
return sb.toString();
}
运行结果
复杂度分析
- 空间复杂度:O(1)
- 时间复杂度:O(n)
在掘金(JUEJIN) 一起分享知识, Keep Learning!