leetcode_[python/C++逐步深入] 43. Multiply Strings_(大数乘法分析)

本篇博客详细分析了LeetCode 43题——大数乘法的解决方案,禁止直接将字符串转换为整数。文中展示了Python利用reduce高效解决方法,以及C++通过翻转数字进行O(mn)复杂度的乘法运算。还探讨了不翻转数字和按位计算的其他思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接
【题目】
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.


【分析】
先看下python的写法:
使用reduce是及其简便的写法,而且效率很高

class Solution(object):
    def multiply(self, num1, num2):
        """
        :type num1: str
        :type num2: str
        :rtype: str
        """
        num1 = reduce(lambda x, y: x * 10 + y, [ord(i) - 48 for i in num1]) # '0' is 48 in ascii
        num2 = reduce(lambda x, y: x * 10 + y, [ord(i) - 48 for i in num2])
        return str(num1 * num2)

打败了95%
这里的[ord(i) - 48 for i in num]可以改写成map形式,会快那么一点点

class Solution(object):
    def multiply(self, num1, num2):
        """
        :type num1: str
        :type num2: str
        :rtype: str
        """       
        i = reduce(lambda x,y : 10 * x + y,map(lambda g:ord(g)-48,num1))
        j = reduce(lambda x,y : 10 * x + y,map(lambda g:ord(g)-48,num2))
        return str(i * j)

99%


C++
将num1,num2翻转
然后两个循环,O(mn)复杂度

class Solution {
public:
    string multiply(string num1, string num2) {
        int size1 = num1.size();
        int size2 = num2.size();
        vector<int> ans(size1+size2,0);
        reverse(num1.begin(),num1.end());
        reverse(num2.begin(),num2.end());
        for(int i=0;i<size1;i++){
            for(int j=0;j<size2;j++){
                ans[i+j] += (num1[i]-'0')*(num2[j]-'0');
                ans[i+j+1] += ans[i+j]/10;
                ans[i+j] = ans[i+j]%10;
            }
        }
        int g;
        string answer="";
        for(g = size1+size2-1;g>0&&ans[g] == 0;g--);
        for(;g>=0;g--){
            answer+=(ans[g]+'0');
        }
        return answer; 

    }
};

discuss里面也有不用翻转的写法,就是简单得索引

string multiply(string num1, string num2) {
    string sum(num1.size() + num2.size(), '0');

    for (int i = num1.size() - 1; 0 <= i; --i) {
        int carry = 0;
        for (int j = num2.size() - 1; 0 <= j; --j) {
            int tmp = (sum[i + j + 1] - '0') + (num1[i] - '0') * (num2[j] - '0') + carry;
            sum[i + j + 1] = tmp % 10 + '0';
            carry = tmp / 10;
        }
        sum[i] += carry;
    }

    int startpos = sum.find_first_not_of("0");
    if (string::npos != startpos) {
        return sum.substr(startpos);//这些操作全都返回 string::size_type 类型的值,
        //以下标形式标记查找匹配所发生的位置;或者返回一个名为 string::npos 的特殊值,
        //说明查找没有匹配。string 类将 npos 定义为保证大于任何有效下标的值。
    }
    return "0";
}

discuss里还有一种java写的按位来计算的方法,效率不是很快但挺开放性的思维原地址戳这里
这里写图片描述

public String multiply(String num1, String num2) {
    int m = num1.length(), n = num2.length();
    int[] pos = new int[m + n];

    for(int i = m - 1; i >= 0; i--) {
        for(int j = n - 1; j >= 0; j--) {
            int mul = (num1.charAt(i) - '0') * (num2.charAt(j) - '0'); 
            int p1 = i + j, p2 = i + j + 1;
            int sum = mul + pos[p2];

            pos[p1] += sum / 10;
            pos[p2] = (sum) % 10;
        }
    }  

    StringBuilder sb = new StringBuilder();
    for(int p : pos) if(!(sb.length() == 0 && p == 0)) sb.append(p);
    return sb.length() == 0 ? "0" : sb.toString();
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值