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.

Note: You must not use any built-in BigInteger library or convert the inputs to integer directly.

 

Example 1:

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

Example 2:

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

 

Constraints:

  • 1 <= num1.length, num2.length <= 200
  • num1 and num2 consist of digits only.
  • Both num1 and num2 do not contain any leading zero, except the number 0 itself.

解法一

解法一出处及相关说明

解法一之所以比较简洁(相比我自己的解法简洁太多了),是因为总结出了一个规律。这个在上一行的链接里有图示。

 num1[i] * num2[j] will be placed at indices [i + j, i + j + 1]

如下是对应的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();
}

解法二

跟解法一思路很像,int(n1)的方法比ord(n1)-ord('0')时间用的多。

可以直接for n1 in reversed(num1):来倒序遍历。比解法四中我自己for j in range(len(num1)-1,-1,-1):的方法简洁,可读性高。

数组转字符串时,由于数组中元素是数字,使用了map函数,map函数的用法为map(function,iterable,...)参数分别为函数和迭代器。python2返回列表;python3返回迭代器,需用list函数转为列表。

def multiply(num1, num2):
    product = [0] * (len(num1) + len(num2))
    pos = len(product)-1
    
    for n1 in reversed(num1):
        tempPos = pos
        for n2 in reversed(num2):
            product[tempPos] += int(n1) * int(n2)
            product[tempPos-1] += product[tempPos]/10
            product[tempPos] %= 10
            tempPos -= 1
        pos -= 1
        
    pt = 0
    while pt < len(product)-1 and product[pt] == 0:
        pt += 1

    return ''.join(map(str, product[pt:]))

解法三

基于解法二进一步优化,主要是1.用了enumerate函数,省去了解法二中tempPos和pos两个代表位置的变量。2.在去掉打头的0时,用了pop函数,可读性高一点

def multiply(self, num1, num2):
        res = [0]* (len(num1) + len(num2))
        for i, e1 in enumerate(reversed(num1)):
            for j, e2 in enumerate(reversed(num2)):
                res[i+j] += int(e1) * int(e2)
                res[i+j+1] += res[i+j]/10
                res[i+j] %= 10
    
        while len(res) > 1 and res[-1] == 0: res.pop()
        return ''.join( map(str,res[::-1]) )

解法四

我自己的做法,耗时久、空间占用多、代码繁琐。因为我完全按照手动计算时的做法,先乘后加。

class Solution:

    def multiply(self, num1: str, num2: str) -> str:
        #若其中一个参数为0,则返回0
        if (num1[0] == '0' or num2[0] == '0'):
            return '0'

        #结果的长度不会超过num1的长度+num2的长度
        result=[0]*(len(num1)+len(num2))

        for i in range(len(num2)-1,-1,-1):
            carry=0
            tmp_res = []
            #乘
            for j in range(len(num1)-1,-1,-1):
                product=(ord(num1[j])-ord('0'))*(ord(num2[i])-ord('0'))+carry
                theValue=product%10
                carry=product//10
                tmp_res.append(theValue)
            if(carry>0):
                tmp_res.append(carry)
            tmp_res.reverse()
            #补0
            for k in range(i,len(num2)-1):
                tmp_res.append(0)

            #加
            carry = 0
            for l in range(len(result)-1,-1,-1):
                tmp_point=l-len(result)+len(tmp_res)
                if(tmp_point>=0):
                    add_result=tmp_res[tmp_point]+result[l]+carry
                    result[l]=add_result%10
                    carry=add_result//10
                    continue
                if(carry>0):
                    result[len(result)-len(tmp_res)-1]=carry
                    break
        if(result[0]==0):
            del result[0]
        return ''.join(str(m) for m in result)

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值