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.
  • Converting the input string to integer is NOT allowed.
  • You should NOT use internal library such as BigInteger.

这道题求的大数乘法,不允许用BigInteger并且不允许将num1和num2转换成int类型。

当然数据非常大,就算把num1和num2转换成int也会溢出。

虽然不允许使用BigInteger,但是可以回忆一下BigInteger。

刚开始使用了双StringBuilder,一个来存储最终结果,一个来存储每一次的乘法结果,虽然AC,但是成绩很差。

public class Solution {
    public String multiply(String num1, String num2) {
        int len1 = num1.length();
        int len2 = num2.length();
        if( len1 > len2)
        	return multiply(num2,num1);
        StringBuilder result = new StringBuilder();
        StringBuilder num ;
        int aa = 0, bb = 0, pos = 0;
        for( int i = len1-1; i>=0;i--){
            if( num1.charAt(i) == 0)
                continue;
            
        	aa = 0;
        	num = new StringBuilder();
        	for( int j = len2-1; j>=0 ; j--){
        		if( num1.charAt(i) == 1){
        		    num.append(num2);
        		    break;
        		}
            	num.insert(0,((num2.charAt(j)-'0')*(num1.charAt(i)-'0')+aa)%10);
        		aa = ((num2.charAt(j)-'0')*(num1.charAt(i)-'0')+aa)/10;
        	}
        	if(aa > 0)
        		num.insert(0, aa);
        	bb = 0;
        	for( int k = num.length()-1 ; k>=0;k--){
        		pos = num.length()-k+len1-2-i;//从右往左数第pos位
        		pos = result.length()-1 - pos;//第pos位
        		if( pos < 0  ){
        			while( pos < 0 ){
        				result.insert(0, num.charAt(k)-'0'+bb);
            			bb = 0;
            			pos++;
        			}
        		}
        		else{
        			int cc = (num.charAt(k)-'0') + (result.charAt(pos)-'0') + bb;
        			result.replace(pos, pos+1, String.valueOf(cc%10));
        			bb = cc/10;
        		}	
        	}
        	if( bb > 0){
        		if( pos == 0 )
        			result.insert(0, String.valueOf(bb));
        		else if( pos > 0)
        			result.replace(pos-1, pos, String.valueOf(result.charAt(pos-1)-'0'+bb));
        	}
        }
        for( int i = 0; i< result.length() ; i++){
        	if( result.charAt(i) == '0'){
        		result.delete(i,i+1);
        		i--;
        	}else
        		break;
        }
        if( result.length() == 0)
        	return "0";
        return result.toString();
    }
}

 然后将StringBuilder转变成int[]:

1。因为一个n位数与一个m位数相乘,最多为m+n位数

2。另一个n位数同样的与一个一位数相乘。那么最多为n+1位数。

这样做避免了对对象的多次操作,提高了速度,但是结果仍旧不是很理想。

public class Solution {
   public String multiply(String num1, String num2) {
        int len1 = num1.length();
		int len2 = num2.length();
		if (len1 > len2)
			return multiply(num2, num1);
		int[] res = new int[len1+len2];
		int pos = 0, aa =0;
		for( int i =len1-1; i>=0;i--){
			if (num1.charAt(i) == '0')
				continue;
			aa = 0;
			for( int j = len2-1; j>=0; j--){
				pos = j+1+i;
				int mi = (num2.charAt(j) - '0')*(num1.charAt(i) - '0') + aa + res[pos];
				res[pos] = mi%10;
				aa = mi/10;			
			}
			if (aa > 0) 
				res[pos-1] =res[pos-1]+ aa;
		}
		
		StringBuilder result = new StringBuilder();
		for (int i = 0; i < res.length; i++) {
			if( !(res[i] == 0 && result.length() == 0))
				result.append(res[i]);
		}
		if( result.length() == 0)
			return "0";
		return result.toString();
}
}

 最后在查找了资料发现,jvm启动时间影响太大,同样的代码运行的时间也会不一样,因此不再纠结于代码速度达到最快。

相比于上一次,最后还是有了一些微调,主要就是进位的操作放在最后一次进行,这大量减少了操作次数,也就提高了运行时间。

public class Solution {
    public static String multiply(String num1, String num2) {
		int len1 = num1.length() ,len2 = num2.length();
		int[] Num2 = ToInt(num2);
		int[] res = new int[len1+len2];
		for( int i =len1-1; i>=0;i--){
			add(num1.charAt(i)-'0',Num2,res,i);
		}
		for( int i = len1+len2-1,b = 0;i>=0;i--){
			int a = res[i] + b;
			res[i] = a%10;
			b = a/10;
		}
		StringBuilder result = new StringBuilder();
		for(int i = 0;i< res.length;i++){
			if( res[i]!= 0 ){
				while( i<res.length){
					result.append(res[i]);
					i++;
				}
			}
		}
		if( result.length() == 0)
			return "0";
		return result.toString();
	}
	public static void add(int num,int[] num1,int[] res,int pos){
		for( int i =num1.length-1 ; i >=0;i--){
			res[i+pos+1] += num*num1[i];
		}
		
	}
	public static int[] ToInt(String num){
		int[] res = new int[num.length()];
		for( int i =0;i<num.length(); i++){
			res[i] = num.charAt(i)-'0';
		}
		return res;
	}
}