【LeetCode】字符串相乘

声明:这只是一个题解,题目是LeetCode来的。著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题目:

43. 字符串相乘

给定两个以字符串形式表示的非负整数 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)或直接将输入转换为整数来处理。

题解:

解法1 拆分相加

分析:

123 * 456 = 123 * 6 + 123 * 50 + 123 * 400;

因此可以通过拆分num1或num2来分别得到每一位的乘积,最后把他们加起来。

实现:(略)

解法2 模拟乘法运算

这也是我一开始思考这道题的时候想到的办法。我们首先来看一下我们小学的时候是怎么算乘法的:

首先看最后的结果,我们可以发现,结果的位数 <= num1.length + num2.length,因此我们可以使用一个length = num1.length + num2.length的数组来保存我们要的结果。

其次,最后的结果实际上是num1和num2的每一位相乘得到的结果再加和。

再次模拟一下过程,找找规律:

我们再次可以发现,当用两个指针分别指向num1和num2的末尾并且向前移动时,num1[i] * num2[j] 的值应该放在 index = i + j + 1的位置上。如果有进位的话,就放在前一个位置上。

那么当123  * 6计算完以后,我们还要计算123 * 5,这时候应该怎么办?

要知道每一次乘法得到的结果最后都是要相加的,那么我们只需要把这一次得到的结果累加在上一次的结果上就行了。有进位的就往前一个位置累加即可,i+j+1对应的位置应该只存放这次得到的个位数。

所以我们的result数组的填充方法应该是:

 int val1 = num1.charAt(i) - '0';
 int val2 = num2.charAt(j) - '0';
 int temp = result[i + j + 1] + val1 * val2;//原来的数字+新乘积
 result[i + j + 1] = temp % 10;//对应位置的数字
 result[i + j] += temp/10; //进位

最后填充完数组,数组可能不满,也就是说结果的最高位之前可能会出现0,比如123 * 456的结果可能是这样[0,5,6,0,8,8]那我们构造结果的时候需要判断一下,遇到第一个是0我们就跳过。为什么只有第一个0跳过?因为结果的大小是在[长的num.length, num1.length + num2.length]之间,所以说最多也就只有1个0在首位。(可以自己写一写看看)

所以整个代码是这样的:

public String multiply(String num1, String num2){
        int len1 = num1.length();
        int len2 = num2.length();
        if(len1 == 0 || len2 == 0 || num1.charAt(0) -'0' == 0 || num2.charAt(0) - '0' == 0) return "0";
        int[] result = new int[len1 + len2];
        for(int i = len1 - 1; i >= 0; i--){
            int val1 = num1.charAt(i) - '0';
            for(int j = len2 - 1; j >= 0; j--){
                int val2 = num2.charAt(j) - '0';
                int temp = result[i + j + 1] + val1 * val2;//原来的数字+新乘积
                result[i + j + 1] = temp % 10;//对应位置的数字
                result[i + j] += temp/10; //进位
            }
        }
        //构造结果
        StringBuilder res = new StringBuilder();
       for(int i = 0; i < result.length; i++){
           if(i == 0 && result[i] == 0) continue;
           res.append(result[i]);
       }
        return res.toString();
    }

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值