Search code examples
pythonalgorithmcomputer-sciencekaratsuba

Multiply strings-Leetcode using Karatsuba algorithm with Python


Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2, also represented as a string.

Example 1:

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

Example 2:

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

Note:

The length of both num1 and num2 is < 110. Both num1 and num2 contain only digits 0-9. Both num1 and num2 do not contain any leading zero, except the number 0 itself. You must not use any built-in BigInteger library or convert the inputs to integer directly.

There are many different approaches to this problem .One of them is by using Karatsuba algorithm .

class Solution:
    def multiply(self, num1: str, num2: str) -> str:
        if len(num1)==1 or len(num2)==1:
            return str(int(num1)*int(num2))
        m=max(len(num1),len(num2))
        m2=m//2   

        num1=int(num1)
        num2=int(num2)
        a=num1//10**m2
        b=num1%10**m2
        c=num2//10**m2
        d=num2%10**m2
        
        z0=self.multiply(str(b),str(c))
        z1=self.multiply(str(a+b),str(c+d))-a*c-b*d
        z2=self.multiply(str(a), str(c))
        
        return (z2 * 10**(2*m2)) + ((z1 - z2 - z0) * 10**(m2)) + (z0)

The Pseudocode applied is correct as but the code is suffering due to repetitive conversion between strings and integer .What can I do to improve upon this ? And is this the correct approach for this problem ? Thanks in advance

Here is the reference link which helped me-https://pythonandr.com/2015/10/13/karatsuba-multiplication-algorithm-python-code/


Solution

  • class Solution:
        def multiply(self, num1: str, num2: str) -> str:
            def mul(num1, num2):
                if len(num1) == 1 or len(num2) == 1:
                    return int(num1) * int(num2)
                m = min(len(num1), len(num2)) // 2
                a, b = num1[:len(num1) - m], num1[len(num1) - m:]
                c, d = num2[:len(num2) - m], num2[len(num2) - m:]
                z0 = mul(b, d)
                z2 = mul(a, c)
                z1 = mul(str(int(a) + int(b)), str(int(c) + int(d))) - z2 - z0
                return (10 ** (2 * m)) * z2 + (10 ** m) * z1 + z0
    
            return str(mul(num1, num2))
    
    

    Originally I was the person who asked the same question, later when I figured it out I'm posting the solution.