Given two numbers represented as strings, return multiplication of the numbers as a string.
Note: The numbers can be arbitrarily large and are non-negative.
实现中有两个小细节,一个是循环中最后有一个if判断,其实就是看最高一位是不是0(最高第二位不可能是0,除非两个源字符串最高位带有0),如果是就不需要加入字符串中了。另一个小问题是我们是由低位到高位放入结果串的,所以最后要进行一次reverse,因为是一个O(m+n)的操作,不会影响算法复杂度。
这道题其实还有更加优的做法,就是用十大最牛的算法之一--Fast Fourier transform(FFT)。使用FFT可以在O(nlogn)时间内求出多项式的乘法,在这里只需要把变量x带入10,然后按照求多项式的方法就可以求出两个大整数的成绩了。想了解细节的朋友搜一下快速傅里叶变换求多项式乘积就可以找到相关资料了,是比较成熟的算法。不过FFT实现不是很简单,所以在面试中一般不需要写代码,只需要知道这个思路和基本工作原理就可以了哈。
思路 2 :其实理解起来很简单, 首先将 两个 string reverse, 这样最终结果的 digits[i + j] += num1[i] * num2[j] , 最后把 大于 9的进位就行了。
易错点: 1, 注意 俩数有个 0 的情况, 2, 最后结果 首字母为0 的情况, 3, stringbuilder 删除某一位 用的 deleteCharAt(i) 而不是 remove(i)
public class Solution {
public String multiply(String num1, String num2) {
if(num1 == null || num2 == null || num1.length()==0 || num2.length()==0)
return "";
if(num1.charAt(0)=='0')
return "0";
if(num2.charAt(0)=='0')
return "0";
StringBuilder res = new StringBuilder();
int num = 0;
for(int i=num1.length()+num2.length();i>0;i--)//----代表第 i 位。
{
for(int j=Math.min(i-1,num1.length());j>0;j--)//----
{
if(i-j<=num2.length())//---
{
num += (int)(num1.charAt(j-1)-'0')*(int)(num2.charAt(i-1-j)-'0'); // (j - 1) + (i - 1 - j) = i
}
}
if(i!=1 || num>0)//---
res.append(num%10);
num = num/10;//---
}
return res.reverse().toString();
}
}
public class Solution {
public String multiply(String num1, String num2) {
if(num1 == null || num2 == null || num1.length() < 1 || num2.length() < 1)
return null;
if(num1.charAt(0) == '0' || num2.charAt(0) == '0'){
return "0";
}
StringBuilder sb1 = (new StringBuilder(num1)).reverse();
StringBuilder sb2 = (new StringBuilder(num2)).reverse();
int[] digits = new int[num1.length() + num2.length()];
for(int i = 0; i < num1.length(); i++){
for(int j = 0; j < num2.length(); j++){
digits[i + j] += (sb1.charAt(i) - '0') * (sb2.charAt(j) - '0');//----
}
}
int carry = 0;
StringBuilder ret = new StringBuilder();
for(int i = 0; i < digits.length; i++){
int digit = carry + digits[i];
ret.append(digit % 10);
carry = digit / 10;
}
if(carry > 0){
ret.append(carry);
}
if(ret.charAt(ret.length() - 1) == '0')
ret.deleteCharAt(ret.length() - 1);//----
return ret.reverse().toString();
}
}
public class Solution {
public String multiply(String num1, String num2) {
if(num1.length() < 1 || num2.length() < 1)
return null;
if(num1.charAt(0) == '0' || num2.charAt(0) == '0')
return "0";
int[] int1Arr = new int[num1.length()];
int[] int2Arr = new int[num2.length()];
int[] resultArr = new int[num1.length() + num2.length()];
//Copy and reverse the string num to integer array
for(int i = 0; i < num1.length(); i++){
int1Arr[i] = num1.charAt(num1.length() - 1 - i) - '0';
}
for(int i = 0; i < num2.length(); i++){
int2Arr[i] = num2.charAt(num2.length() - 1 - i) - '0';
}
//Mutiply the numbers from int1Arr and int2Arr, but in every digit the number may larger than 10
for(int i = 0; i < num1.length(); i++){
for(int j = 0; j < num2.length(); j++){
resultArr[i + j] += int1Arr[i] * int2Arr[j];
}
}
// Carry carrier if the number in one digit larger than 10
int carrier = 0;
for(int i = 0; i < resultArr.length; i++){
int digit = (resultArr[i] + carrier) % 10;
carrier = (resultArr[i] + carrier) / 10;
resultArr[i] = digit;
}
//Copy the number from integer array to StringBuilder
StringBuilder sb = new StringBuilder();
for(int i : resultArr)
sb.append(i);
sb = sb.reverse();
//If the first digit is 0 , it is useless digit.
if(sb.charAt(0) == '0'){
return sb.substring(1, sb.length());
}
return sb.toString();
}
}