力扣43-字符串相乘(最简单算法)

力扣43-字符串相乘-最容易理解算法
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。


一、问题描述

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。

二、示例

示例一:

示例一

示例二

示例二

三、提示

  • 1 <= num1.length, num2.length <= 200
  • num1 和 num2 只能由数字组成。
  • num1 和 num2 都不包含任何前导零,除了数字0本身。

四、问题分析

本题题目看起来很简单,给定两个只包含的数字的字符串,我们需要计算这两个字符串对应的数字的乘积。
这里要特别注意,用int或者long类型来计算都是不行的,因为这里的字符串也许会很长,超过范围。、
相当于两个大整数相乘问题

五、解法

public String multiply(String num1, String num2) {
        //如果这两个字符串任意一个为"0"时,直接返回"0"
        if (num1.equals("0") || num2.equals("0")) {
            return "0";
        }
        int m = num1.length(), n = num2.length();
        //两个整数相乘,积的位数不会超过这两个数的位数和
        //例如:99+99=198不会超过4位数
        //所以我们定义一个长度为m+n的数组
        int[] ansArr = new int[m + n];
        //根据乘法的规律,给数组赋值
        for (int i = m - 1; i >= 0; i--) {
            int x = num1.charAt(i) - '0';
            for (int j = n - 1; j >= 0; j--) {
                int y = num2.charAt(j) - '0';
                //i+j+1即代表这个乘积所在的位置
                ansArr[i + j + 1] += x * y;
            }
        }
        //准备一个StringBuilder字符串来存储结果
        StringBuilder sb=new StringBuilder();
        int val=0;
        int num=0;
        for (int i = ansArr.length-1; i >=0; i--) {
            //num是这一位的值
            num=(ansArr[i]+val)%10;
            //val是向前一位进的值
            val=(ansArr[i]+val)/10;

            //当i=0时,不用拼接
            if(!(i==0&&num==0)) {
                sb.append(num);
            }
        }
        //因为字符串的拼接是从后往前,所以结果应当是对sb反转
        return sb.reverse().toString();
    }

六、代码分析

如果这两个字符串任意一个为"0"时,直接返回"0"

    if (num1.equals("0") || num2.equals("0")) {
        return "0";
    }

使用数组来存储每一位的乘运算结果

int m = num1.length(), n = num2.length();
//两个整数相乘,积的位数不会超过这两个数的位数和
//例如:99+99=198不会超过4位数
//所以我们定义一个长度为m+n的数组
int[] ansArr = new int[m + n];
//根据乘法的规律,给数组赋值
for (int i = m - 1; i >= 0; i--) {
    int x = num1.charAt(i) - '0';
    for (int j = n - 1; j >= 0; j--) {
        int y = num2.charAt(j) - '0';
        //i+j+1即代表这个乘积所在的位置
        ansArr[i + j + 1] += x * y;
    }
}

如图所示,这里的for循环运算过程如图所示,不用考虑进位
请添加图片描述
此时,“12345”*“123”存储在数组中的结果就是
[0, 1, 4, 10, 16, 22, 22, 15]

因为要返回一个字符串,所以我们使用一个StringBuilder来存储结果

StringBuilder sb=new StringBuilder();
        int val=0;
        int num=0;
        for (int i = ansArr.length-1; i >=0; i--) {
            //num是这一位的值
            num=(ansArr[i]+val)%10;
            //val是向前一位进的值
            val=(ansArr[i]+val)/10;
            //当i=0时,不用拼接
            if(!(i==0&&num==0)) {
                sb.append(num);
            }
        }
        //因为字符串的拼接是从后往前,所以结果应当是对sb反转
        return sb.reverse().toString();

七、运行结果

结果
这个算法的时空复杂度都比较简单。希望能帮到大家!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值