★leetcode43_Multiply Strings

一.问题描述

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.

实现字符串的乘法,不能直接将字符串转化成int哦~


二.代码编写

首先想到的方法就是根据我们平时手算乘法的方法来计算,本质上就是移位相乘相加~

但是时间复杂度是O(N^2)。代码如下:

'''
@ author: wttttt at 2016.10.29
@ problem description see: https://leetcode.com/problems/longest-valid-parentheses/
@ solution explanation see: http://blog.csdn.net/u014265088/article/details/52962971
@ github:https://github.com/wttttt-wang/leetcode
@ string [time complexity O(N^2)] , common way of multiplying
@ also see ../../Divide_and_Conquer/43MultiplyStrings [use Divide and Conquer, O(N^log3)]
@ for more imformation of multiplication algo, see https://en.wikipedia.org/wiki/Multiplication_algorithm#Fast_multiplication_algorithms_for_large_inputs'''
class Solution(object):
    def multiply(self, num1, num2):
        """
        :type num1: str
        :type num2: str
        :rtype: str
        """
        '''
        two problems need to be solved:
        a. how to calculate the multiplication
        b. overflow [for python
        for problem a: do multiplication on each number, and then add it together.
        for problem b: u need to check if x>sys.maxint, because that python do automatic transfer to long when overflow
        '''
        len_num1 = len(num1)
        len_num2 = len(num2)
        sum = 0
        for i in range(len_num1):
            if num1[i] == 0:
                continue
            x = int(num1[i]) * (10 ** (len_num1 - i - 1))
            for j in range(len_num2):
                y = int(num2[j]) * (10 ** (len_num2 - j - 1))
                sum += int(x) * int(y)
        return str(sum)

so = Solution()
num1 = '1'
num2= '1'
print so.multiply(num1,num2)


三.算法优化

上述实现很简单,但是因为题目是medium的,而且ac的效率很低,遂百度了一下发现:大数相乘还有两种优化的方法:

1)Karatsuba算法,本质上是分治法,通过拆分要相乘的数,可以减少时间复杂度,具体如下:

solution: using Divide_and_Conquer
num1 = A*10^m+B
num2 = C*10^m+D
then num1*num2 = A*C*10^(2m)+[(A-B)(D-C)+AC+BD]*10^m+BD
               = A*C*(10^2m+10^m)+B*D*(10^m+1)+(A-B)(D-C)*10^m

Karatsuba乘法,对于给定的n位大数,算法的复杂度不超过3nlog3 ≈ 3n1.585


2)通过快速傅里叶变换FFT

# to be continued...

see wiki_multiplication_algorithm


Karatsuba/分治法实现代码如下:

'''
@ author: wttttt at 2016.10.29
@ problem description see: https://leetcode.com/problems/longest-valid-parentheses/
@ solution explanation see: http://blog.csdn.net/u014265088/article/details/52962971
@ github:https://github.com/wttttt-wang/leetcode
@ Divide_and_Conquer [time complexity O(N^log3)]
@ also see ../data_structure/string/43MultiplyStrings [common multiplication, O(N^2) ]
@ for more imformation of multiplication algo, see https://en.wikipedia.org/wiki/Multiplication_algorithm#Fast_multiplication_algorithms_for_large_inputs
'''class Solution(object): def multiply_1(self, num1, num2): """ :type num1: str :type num2: str :rtype: str """ ''' solution: using Divide_and_Conquer num1 = A*10^m+B num2 = C*10^m+D then num1*num2 = A*C*10^(2m)+[(A-B)(D-C)+AC+BD]*10^m+BD = A*C*(10^2m+10^m)+B*D*(10^m+1)+(A-B)(D-C)*10^m ''' len_num1 = len(num1) len_num2 = len(num2) m = min(len_num1,len_num2)/2 if m<1: return int(num2)*int(num1) num1_a = num1[:(0-m)] num1_b = num1[(len_num1-m):] num2_c = num2[:(0-m)] num2_d = num2[(len_num2-m):] return self.multiply_1(num1_a,num2_c)*(10**(m*2)+10**m) + self.multiply_1(num1_b,num2_d)* \ (10**m+1) + (int(num1_a)-int(num1_b))*(int(num2_d)-int(num2_c))*10**m def multiply(self, num1, num2): """ :type num1: str :type num2: str :rtype: str """ return str(self.multiply_1(num1,num2))so = Solution()num1 = '110'num2= '11'print so.multiply(num1,num2)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值