一.问题描述
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
# 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) ]
'''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)@ for more imformation of multiplication algo, see https://en.wikipedia.org/wiki/Multiplication_algorithm#Fast_multiplication_algorithms_for_large_inputs