LeetCode 43. Multiply Strings

一 题目

Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2, also represented as a string.

Example 1:

Input: num1 = "2", num2 = "3"
Output: "6"

Example 2:

Input: num1 = "123", num2 = "456"
Output: "56088"

Note:

  1. The length of both num1 and num2 is < 110.
  2. Both num1 and num2 contain only digits 0-9.
  3. Both num1 and num2 do not contain any leading zero, except the number 0 itself.
  4. You must not use any built-in BigInteger library or convert the inputs to integer directly.

二 分析

求两个数的乘积,限制了直接转换位integer操作,medium级别难度,之前做过一个除法  leetcode 29. Divide Two Integers

这个乘法本来想试试。

public static String multiply(String num1, String num2) {
		//conercase
		if(num1.equals("0")|| num2.equals("0")){
			return "0";
		}		
		//转换为数字
		Double n1=0d;
        for(int i=0;i<num1.length();i++){
        	n1=n1+ Math.pow(10, num1.length()-1-i ) *(num1.charAt(i)-'0') ;        	
        }		
		Double n2 = 0d;
		for(int i=0;i<num2.length();i++){
        	n2=n2+ Math.pow(10, num2.length()-1-i ) *(num2.charAt(i)-'0') ;        	
        }		
		return  String.valueOf(n1 * n2) ;        
    }

很快就会放弃了,因为case例子超过了integer、long的限制。如:"498828660196","840477629533"。题目的限制是长度《110.

看了下讨论区的解决方法,居然是回到了小学的时候多位数乘法,错位相加的办法。没有什么骚操作,真是不忘初心啊。

图片来自:https://leetcode.com/problems/multiply-strings/discuss/17605/Easiest-JAVA-Solution-with-Graph-Explanation

       只靠朴素的理解按位相乘错位相加是不够的。还要找规律:

  • 1 .num1 长度为m,num2 长度为n,则 num1 x num2 的长度不会超过 m+n。2
  • 2. 作者画图是想说明,num1 和 num2 中任意位置的两个数字相乘,得到的两位数在最终结果中的位置是确定的,比如 num1 中位置为i的数字乘以 num2 中位置为j的数字,那么得到的两位数(个位数相乘结果可能为0-81)字的位置为 i+j 和 i+j+1
 `num1[i] * num2[j]` will be placed at indices `[i + j`, `i + j + 1]` 

 

 

还是从个位开始,从低往高计算。对应的遍历顺序就是 num1 和 num2 字符串的尾部开始往前遍历。 某一位的计算还是要转换为数字再相乘。 然后根据上面的规律确定相乘后的两位数所在的位置 p1 和 p2,把乘积放到对应的位置,要先从个位p2开始放,还要考虑到+p2后进位的情况。

   最后是是吧结果pos从高往低输出。要注意过滤掉开头的“0”

public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println( multiply("498828660196","840477629533") );
	}
	
	public static String multiply(String num1, String num2) {
		if(num1.equals("0")||num2.equals("0")){
			return "0";
		}
		int m = num1.length(), n = num2.length();
		//规律发现,相乘的长度不会超过m+n
		int[] pos = new int[m + n];
        
		//从低位到高位遍历
		for(int i=m-1;i>=0;i--){
			for(int j=n-1;j>=0;j--){
				int tmp = (num1.charAt(i) - '0') * (num2.charAt(j) - '0'); 
				//这里就是图上的规律,吧乘积放到对应位置
				int p1 = i+j; int p2 =i+j+1;
				//先加个位的数字
				int sum = tmp + pos[p2];
				 //考虑进位的情况:
				 pos[p1] += sum / 10;
				 //进位后剩余的个位
		         pos[p2] = (sum) % 10;
			}
			
		}
		 StringBuilder sb = new StringBuilder();
		    //从高位开始输出结果
		    for(int i=0; i<pos.length; i++){
		    	//过滤掉开头的0
		    	if(sb.length() == 0 && pos[i] == 0){
		    		continue;
		    	}
		        sb.append(pos[i]);
		    }	
		    return sb.toString();
	}

 

Runtime: 4 ms, faster than 86.79% of Java online submissions for Multiply Strings.

Memory Usage: 36.1 MB, less than 100.00% of Java online submissions for Multiply Strings.

真心佩服大神们。自己真心做不出来啊。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值