LeetCode第43题思悟——字符串相乘(multiply-strings)
知识点预告
- 数组的存储功能;
- 乘法中进位的处理;
- 乘法中结果与乘数的位置关系;
题目要求
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/multiply-strings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
示例
示例 1:
输入: num1 = “2”, num2 = “3”
输出: “6”
示例 2:输入: num1 = “123”, num2 = “456”
输出: “56088”
说明:num1 和 num2 的长度小于110。
num1 和 num2 只包含数字 0-9。
num1 和 num2 均不以零开头,除非是数字 0 本身。
不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/multiply-strings
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
我的思路
模拟乘法运算即可解决——个位乘法+加法;需要注意的是不允许使用任何标准库的大数类型,说明结果最后一定会溢出int甚至long型;所以只能使用字符串连接去拼结果啦;
public String multiply(String num1, String num2) {
if(num1.equals("0")||num2.equals("0")){
return "0";
}
if(num1.length()>num2.length()){
return multiply(num2,num1);
}
char[] numChars1=num1.toCharArray();
char[] numChars2=num2.toCharArray();
String result="";
int firstInt;
String tempValue;
int bitNums=0,zeroNum;
int startIndex=numChars1.length-1;
for(int i=startIndex;i>=0;i--){
firstInt=numChars1[i]-'0';
if(firstInt!=0){
tempValue=multiplyHelper(firstInt,numChars2);
zeroNum=bitNums;
while(zeroNum>0){
zeroNum--;
tempValue=tempValue+'0';
}
result=add(tempValue,result);
}
bitNums++;
}
return result;
}
private String multiplyHelper(int firstValue,char[]secondValues){
String result="";
int carryFlag=0;
int currentValue;
int startIndex=secondValues.length-1;
for(int i=startIndex;i>=0;i--){
currentValue=firstValue*(secondValues[i]-'0')+carryFlag;
carryFlag=currentValue/10;
currentValue=currentValue-carryFlag*10;
result=currentValue+result;
}
if(carryFlag!=0){
result=carryFlag+result;
}
return result;
}
public String add(String firstValue,String secondValue){
int shortLength=firstValue.length();
int longLength=secondValue.length();
if(shortLength>longLength){
return add(secondValue,firstValue);
}
String result="";
char[] firstChars=firstValue.toCharArray();
char[] secondChars=secondValue.toCharArray();
int firstInt,secondInt,carryFlag=0,temp;
int secondIndex=longLength-1;
int firstIndex=shortLength-1;
while(firstIndex>=0){
firstInt=firstChars[firstIndex]-'0';
secondInt=secondChars[secondIndex]-'0';
temp=firstInt+secondInt+carryFlag;
if(temp>=10){
carryFlag=1;
temp-=10;
}else{
carryFlag=0;
}
result=temp+result;
firstIndex--;
secondIndex--;
}
while(secondIndex>=0){
temp=secondChars[secondIndex]-'0'+carryFlag;
if(temp>=10){
carryFlag=1;
temp-=10;
}else{
carryFlag=0;
}
result=temp+result;
secondIndex--;
}
if(carryFlag!=0){
result=1+result;
}
return result;
}
优秀解法
public String multiply(String num1, String num2) {
if("0".equals(num1) || "0".equals(num2))
return "0";
int n = num1.length() + num2.length();
int[] temp = new int[n];
String res = "";
for(int i = num1.length() - 1; i >=0; i--){
for(int j = num2.length() -1; j >= 0; j--){
temp[n - 2 -i - j] += (num1.charAt(i) - '0') * (num2.charAt(j) - '0');
}
}
for(int i = 0; i < n - 1; i++){
temp[i + 1] += temp[i] / 10;
temp[i] %= 10;
res = (char)(temp[i] + '0') + res;
}
if(temp[n - 1] != 0)
res = (char)(temp[n - 1] + '0') + res;
return res;
}
差异分析
不得不承认,优秀解法更加灵巧;自己的解法更像是买一送二:送字符串的加法、送字符与字符串的乘法;换言之,是把问题复杂化了。没有跳出“字符串”的圈;
优秀解法的精彩之处在于使用数组作为字符的容器,而这一技巧,我们在之前是见到过的:数组的容器功能;而且我没有发现乘法运算时i与j与其结果所在位置的关系;
n-2-j-i是保证结果的存储将从0开始;而进位的问题,优秀解法选择了统一处理;给人一种整齐的感觉;
知识点小结
- 数组的存储功能;
- 乘法中进位的处理;
- 乘法中结果与乘数的位置关系;