力扣43-字符串相乘-最容易理解算法
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
文章目录
一、问题描述
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
二、示例
示例一:
示例二
三、提示
- 1 <= num1.length, num2.length <= 200
- num1 和 num2 只能由数字组成。
- num1 和 num2 都不包含任何前导零,除了数字0本身。
四、问题分析
本题题目看起来很简单,给定两个只包含的数字的字符串,我们需要计算这两个字符串对应的数字的乘积。
这里要特别注意,用int或者long类型来计算都是不行的,因为这里的字符串也许会很长,超过范围。、
相当于两个大整数相乘问题
五、解法
public String multiply(String num1, String num2) {
//如果这两个字符串任意一个为"0"时,直接返回"0"
if (num1.equals("0") || num2.equals("0")) {
return "0";
}
int m = num1.length(), n = num2.length();
//两个整数相乘,积的位数不会超过这两个数的位数和
//例如:99+99=198不会超过4位数
//所以我们定义一个长度为m+n的数组
int[] ansArr = new int[m + n];
//根据乘法的规律,给数组赋值
for (int i = m - 1; i >= 0; i--) {
int x = num1.charAt(i) - '0';
for (int j = n - 1; j >= 0; j--) {
int y = num2.charAt(j) - '0';
//i+j+1即代表这个乘积所在的位置
ansArr[i + j + 1] += x * y;
}
}
//准备一个StringBuilder字符串来存储结果
StringBuilder sb=new StringBuilder();
int val=0;
int num=0;
for (int i = ansArr.length-1; i >=0; i--) {
//num是这一位的值
num=(ansArr[i]+val)%10;
//val是向前一位进的值
val=(ansArr[i]+val)/10;
//当i=0时,不用拼接
if(!(i==0&&num==0)) {
sb.append(num);
}
}
//因为字符串的拼接是从后往前,所以结果应当是对sb反转
return sb.reverse().toString();
}
六、代码分析
如果这两个字符串任意一个为"0"时,直接返回"0"
if (num1.equals("0") || num2.equals("0")) {
return "0";
}
使用数组来存储每一位的乘运算结果
int m = num1.length(), n = num2.length();
//两个整数相乘,积的位数不会超过这两个数的位数和
//例如:99+99=198不会超过4位数
//所以我们定义一个长度为m+n的数组
int[] ansArr = new int[m + n];
//根据乘法的规律,给数组赋值
for (int i = m - 1; i >= 0; i--) {
int x = num1.charAt(i) - '0';
for (int j = n - 1; j >= 0; j--) {
int y = num2.charAt(j) - '0';
//i+j+1即代表这个乘积所在的位置
ansArr[i + j + 1] += x * y;
}
}
如图所示,这里的for循环运算过程如图所示,不用考虑进位
此时,“12345”*“123”存储在数组中的结果就是
[0, 1, 4, 10, 16, 22, 22, 15]
因为要返回一个字符串,所以我们使用一个StringBuilder来存储结果
StringBuilder sb=new StringBuilder();
int val=0;
int num=0;
for (int i = ansArr.length-1; i >=0; i--) {
//num是这一位的值
num=(ansArr[i]+val)%10;
//val是向前一位进的值
val=(ansArr[i]+val)/10;
//当i=0时,不用拼接
if(!(i==0&&num==0)) {
sb.append(num);
}
}
//因为字符串的拼接是从后往前,所以结果应当是对sb反转
return sb.reverse().toString();
七、运行结果
这个算法的时空复杂度都比较简单。希望能帮到大家!