题目描述:
给定两个以字符串形式表示的非负整数 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)或直接将输入转换为整数来处理。
解题思路:
首先我考虑的是按照题目的要求 按步骤走,先将字符串转换为整数,再将相乘得到的整数转回字符串。
附上代码:
class Solution {
public static String multiply(String num1, String num2) {
int number1 = stringToInt(num1);
int number2 = stringToInt(num2);
int result = number1 * number2;
return intToString(result);
}
//字符串转整数
public static int stringToInt(String s) {
//将字符串转为字符数组
char[] num = s.toCharArray();
int sum = 0;
for (int i = 0; i < num.length; i++) {
//将char转为对应的int类型整数
int gewei = num[i] - 48;
sum += gewei * Math.pow(10, num.length - i - 1);
}
return sum;
}
//整数转字符串
public static String intToString(int num) {
return "" + num;
}
}
运行结果:
还是太年轻。发现解答错误,结果溢出了。上网查了一下相关解答,这才意识到本道题的出题用意所在,即用手工作乘法的算法直接计算两个两数的乘积,将乘法转为加法,解决了基本数据类型溢出的问题。
主要思想就是将每一位与另一个整数的每一位做乘法,求得乘积,将乘积的每一位分解为各个位,个位结果与本位的进位数相加保留在本位,本位的进位数与结果中的进位数相加保留在进位位。依次类推。
代码实现:
class Solution {
public static String multiply(String num1, String num2) {
if (num1.length() == 0 || num2.length() == 0 || num1 == null || num2 == null) {
return "0";
}
int length1 = num1.length();
int length2 = num2.length();
int[] result = new int[length1 + length2];
for(int j = length2 - 1;j >= 0;j--) {
for(int i = length1 - 1; i >= 0;i--) {
int carryBit = i + j; //进位位
int unitBit = i + j + 1; //本位
int mulNumber = (num1.charAt(i) - '0') * (num2.charAt(j) - '0') + result[unitBit]; //两数相乘并在本位加上进位数
result[unitBit] = mulNumber % 10; //存放本位结果
result[carryBit] += mulNumber / 10; //存放进位结果
}
}
//去掉前导0
StringBuilder builder = new StringBuilder();
for (int i : result) {
if (i == 0 && builder.length() == 0) { //若builder中为空且i ==0,说明为前导零,忽略
continue;
}
builder.append(i);
}
return builder.length() == 0? "0" : builder.toString();
}
}
运行结果: