Leetcode演算法——43、字串相乘
阿新 • • 發佈:2018-12-04
給定兩個非負整數字符串 num1 和 num2,返回兩個數的乘積字串。
備註:
- 兩個整數字符串的長度都 < 110。
- 兩個數都只包含數字 0-9。
- 兩個數都不以0開頭,除非整個字串就是0.
- 不能使用任何內建的大整數庫,不能將輸入字串直接轉為整數。
示例:
Example 1:
Input: num1 = "2", num2 = "3"
Output: "6"
Example 2:
Input: num1 = "123", num2 = "456"
Output: "56088"
思路
既然不能使用內建的大整數乘法,那麼可以使用乘法的手算規則,從低位到高位依次相乘。
比如兩個數為 ‘abcd’ 和 ‘efg’,則手算規則為:
a b c d
* e f g
-----------
ag bg cg dg
af bf cf df
ae be ce de
---------------------
... dg
使用這種方法,可以將兩個大數的乘法,轉化為多個個位數的乘法,然後進行累加。
注意,累加的時候,也不能直接用兩個大數的加法,也按照多個數相加的手算規則,從個位開始,依次相加,並且記錄對高位的進位。
由於乘法和加法都是分解成個位數的加法和乘法,因此輸入的兩個整數字符串理論上可以無限長(不超過記憶體)。
python實現
def multiply(num1, num2):
"""
:type num1: str
:type num2: str
:rtype: str
"""
if num1 == '0' or num2 == '0':
return '0'
def submultiply(large, single):
'''
一個字串和單一字元相乘
返回一個字元陣列,低位在前。
'''
if single == '0':
return ['0']
single = int(single)
result = []
l = len(large)
carry = 0 # 向前進位
for i in range(l):
char = large[l-1-i] # 倒序取出
num = int(char)
mul = num * single + carry # 相乘並加上進位
carry = mul // 10
mul -= 10 * carry
result.append('%d' % mul)
if carry > 0: # 最高位乘完之後還有進位
result.append('%d' % carry)
return result
# num2的每一位與num1相乘,結果放入 mul_list
mul_list = []
for i in range(len(num2)):
single = num2[-1-i]
mul = ['0'] * i + submultiply(num1, single)
mul_list.append(mul)
# 所有 mul_list 相加
result_list = []
carry = 0 # 進位
for i in range(len(mul_list[-1])): # 最長陣列的位數
total = carry # 所有 result_list 第 i 位相加
for string in mul_list:
if len(string) <= i: # 略過長度不夠的陣列
continue
total += int(string[i])
carry = total // 10
total -= 10 * carry
result_list.append('%d' % total)
if carry > 0:
result_list.append('%d' % carry)
return ''.join(result_list)[::-1]
if '__main__' == __name__:
num1 = ['1'] * 100
num2 = ['2'] * 100
print(multiply(num1, num2))