LeetCode 43字符串相乘

LeetCode 43字符串相乘

  • 题目简述:给定两个以字符串形式表示的非负整数 num1num2,返回 num1num2 的乘积,它们的乘积也表示为字符串形式。

  • 输入:num1 = “2”, num2 = “3” 输出:“6”

    输入:num1 = “123”, num2 = “456” 输出:“56088”

  • 说明

    • num1 和 num2 的长度小于 110。
    • num1 和 num2 只包含数字 0-9。
    • num1 和 num2 均不以零开头,除非是数字 0 本身。
    • 不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。
  • 思路:高精度乘法

    模拟乘法竖式运算过程,乘法的最大长度是两个乘数长度之和m+n,时间复杂度是O(nm)

class Solution {
public:
    string multiply(string num1, string num2) {
        int n = num1.size(), m = num2.size();
        vector<int> a(n), b(m), c(n+m);
        //数组低位下标对应数字个位,高位下标对应数字高位
        for(int i = 0; i < n; i++) a[n - 1 - i] = num1[i] - '0';
        for(int j = 0; j < m; j++) b[m - 1 - j] = num2[j] - '0';

        for(int i = 0; i < n; i++)
        {
            for(int j = 0; j < m; j++)
            {
                c[i + j] += a[i] * b[j];
                c[i + j + 1] += c[i + j] / 10;
                c[i + j] %= 10; 
            }
        }
        int l = n + m;
        while (l > 1 && c[l - 1] == 0) l--;//去掉前导0

        string ans;
        for(int i = l - 1; i >= 0; i--)
            ans += c[i] + '0';

        return ans;
    }
};
  • 简化写法:num1[i]num[j]的乘积位置对应c[i+j]c[i+j+1]这两个位置,将低位c[i+j]的数累加,高位c[i+j+1]的数取余进位,给下一个高位
class Solution {
public:
    string multiply(string num1, string num2) {
        int n = num1.size(), m = num2.size();
        vector<int> c(n+m);

        //从个位开始逐位相乘
        for(int i = n - 1; i >= 0; i--)
        {
            for(int j = m - 1; j >= 0; j--)
            {
                int mul = (num1[i] - '0')*(num2[j] - '0');
                int sum = mul + c[i + j + 1];
                c[i + j + 1] = sum % 10;
                c[i + j] += sum / 10; 
            }
        }
        //去掉前导0
        int l = 0;
        while (l < c.size() && c[l] == 0) l++;
        // 将计算结果转化成字符串
        string ans;
        for(; l < c.size(); l++)
            ans += c[l] + '0';

        return ans.size() == 0 ? "0" : ans;
    }
};
  • 思路二:一开始不考虑进位,直接将每位乘积和存入数组,最后统一处理进位
class Solution {
public:
    string multiply(string num1, string num2) {
        int n = num1.size(), m = num2.size();
        vector<int> c(n+m, 0);
        //不考虑进位,直接将每个位乘积存入数组,c[0]存个位乘积,+=累积每位的乘积和
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
                c[i + j] += (num1[n - i - 1] - '0') * (num2[m - 1 - j] - '0');
                //cout << i << j << c[i + j] << endl;//查看数组每位情况
         
        //统一处理数组进位
        for(int i = 0; i < n + m; i++)
        {
            if(c[i] > 9)//比9大就产生进位
            {
                int t = c[i];
                c[i] = t % 10;
                c[i + 1] += (t / 10); 
            }
        }
                
        //去掉前导0
        int l = n + m;
        while (l > 1 && c[l - 1] == 0) l--;
        // 将计算结果转化成字符串
        string ans;
        for(int i = l - 1; i >= 0; i--)
            ans += c[i] + '0';

        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值