Thursday, September 24, 2020

[LeetCode] Fraction to Recurring Decimal

Problem: Given two integers representing the numerator and denominator of a fraction, return the fraction in string format. If the fractional part is repeating, enclose the repeating part in parentheses.

Example: 

Input: numerator = 1, denominator = 5
Output: "0.2"
Input: numerator = 18, denominator = 3
Output: "6"
Input: numerator = 10, denominator = 3
Output: "0.(3)"
Input: numerator = 3, denominator = 333
Output: "0.(012)"
Input: numerator = 1, denominator = 6
Output: "0.1(6)"
Input: numerator = -50, denominator = 8
Output: "-6.25"


Approach: If you see, I have given many examples here specially to cover many scenarios. The approach is not complex, its straight forward. The only problem is to detect if there is recurrence in division. We can detect it using hash of remainders. The points here which we need to be careful of -

  1. What is the sign of the result.
  2. Check for denominator if it is 0.
  3. Deal with int.MinValue as abs(int.MinValue) will throw exception. We can use long instead of int to deal with it.
That's all!


Implementation in C#:

        public static string FractionToDecimal(int numerator, int denominator)
        {
            if (numerator == 0)
            {
                return "0";
            }

            if (denominator == 0)
            {
                throw new DivideByZeroException();
            }

            string sign = (numerator < 0 && denominator > 0) || (numerator > 0 && denominator < 0) ? "-" : string.Empty;
            long numer = Math.Abs((long)numerator);
            long deno = Math.Abs((long)denominator);
            string result = string.Empty;
            result += (numer / deno).ToString();
            if (numer % denominator == 0)
            {
                return sign + result;
            }

            result += ".";
            long remainder = numer % deno;
            Dictionary<long, int> remainders = new Dictionary<long, int>();
            while(remainder != 0 && !remainders.ContainsKey(remainder))
            {
                remainders.Add(remainder, result.Length); // storing length to see from where we need to put (
                result += ((remainder * 10) / deno).ToString();
                remainder = ((remainder * 10) % deno);
            }

            if (remainder != 0)
            {
                result = result.Insert(remainders[remainder], "(");  
                result += ")";
            }

            return  sign + result;
        }

No comments:

Post a Comment