Why memoization is not speeding up recursive problem of converting integers to Words

62 Views Asked by At

I am using following code to optimize the speed of the overall program execution. This program execution involves memoization. ( i.e. I am maintaining the results in an existing dictionary and using the results if the key is found , which causes in the normal recursion a complete tree.

However, while submitting the code at leetcode, i dont see any performance benifit. The runtime stays exactly in the same bracket and it does not provides any benifit.

Am I doing somehitng wrong?

Following with the memoization code :

Dictionary<long, string> memoizationDictionary = new Dictionary<long, string>();


string[] lessThanTwentyWords = new string[] { "","One","Two", "Three", "Four", "Five", "Six",
                                                  "Seven","Eight","Nine", "Ten","Eleven","Twelve",
                                                  "Thirteen","Fourteen","Fifteen","Sixteen",
                                                  "Seventeen","Eighteen","Nineteen"
                                            };

string[] tens = new string[] { "", "Ten", "Twenty", "Thirty", "Fourty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety" };

string ConvertNumsToWords(long num, string[] lessThanTwentyWords, string[] tens)
{
    long result = 1;
    long rem = 0;

    // Check if the result is already memoized
    if (memoizationDictionary.ContainsKey(num))
    {
        if( memoizationDictionary.TryGetValue(num, out var memoizedResult))
        {
            return memoizedResult;
        }
    }

    if (num == 0)
        return "";

    if (num >= 1 && num < 20)
    {
        memoizationDictionary[num] = lessThanTwentyWords[num];

        return memoizationDictionary[num];
    }

    if ((num / 1000000000) > 0)
    {
        rem = num % 1000000000;
        result = num / 1000000000;

        memoizationDictionary[num] = ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Billion" + 
                                     (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");

        return memoizationDictionary[num];
    }

    if ((num / 1000000) > 0)
    {
        rem = num % 1000000;
        result = num/1000000;

        memoizationDictionary[num] = ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Million" + 
                                     (rem != 0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");

        return memoizationDictionary[num];
    }

    if ((num / 1000) > 0)
    {
        rem = num % 1000;
        result = num/ 1000;

        memoizationDictionary[num] = ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " +"Thousand" + 
                                     (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");

        return memoizationDictionary[num];
    }

    if ((num / 100) > 0)
    {
        rem = num % 100;
        result = num/100;

        memoizationDictionary[num] = ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Hundred" + 
                                     (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");

        return memoizationDictionary[num];
    }
    else
    {
        if (num >= 20)
        {
            memoizationDictionary[num] = tens[num / 10] + (num % 10 != 0 ? (" " + lessThanTwentyWords[num % 10]) : "");
            return memoizationDictionary[num];
        }

        return "";
    }    
}

While following is the normal recursive call code.

string ConvertNumsToWords(long num, string[] lessThanTwentyWords, string[] tens)
    {
        long result = 1;
        long rem = 0;

        if (num == 0)
        return "";
    
        if (num >= 1 && num < 20)
        return lessThanTwentyWords[num];

        if ((num / 1000000000) > 0)
        {
            rem = num % 1000000000;
            result = num / 1000000000;

            return ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Billion" + (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");
        }

        if ((num / 1000000) > 0)
        {
            rem = num % 1000000;
            result = num/1000000;

            return ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Million" + (rem != 0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");        
        }

        if ((num / 1000) > 0)
        {
            rem = num % 1000;
            result = num/ 1000;

            return ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " +"Thousand" + (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");
        }

        if ((num / 100) > 0)
        {
            rem = num % 100;
            result = num/100;

            return ConvertNumsToWords(result, lessThanTwentyWords, tens) + " " + "Hundred" + (rem !=0 ? (" " + ConvertNumsToWords(rem, lessThanTwentyWords, tens)) : "");
        }
        else
        {
            if (num >= 20)
            {            
                return tens[num / 10] + (num % 10 != 0 ? (" " + lessThanTwentyWords[num % 10]) : "");
            }

            return "";
        }    
    }

Following is the leet code performance indicator which was same(some time even better in old approach )

So far, I didn't try to investigate as the test cases of leetcode are not attainable.

0

There are 0 best solutions below