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.
If multiple answers are possible, return any of them.
It is guaranteed that the length of the answer string is less than 104
for all the given inputs.
Example 1:
Input: numerator = 1, denominator = 2 Output: "0.5"
Example 2:
Input: numerator = 2, denominator = 1 Output: "2"
Example 3:
Input: numerator = 4, denominator = 333 Output: "0.(012)"
Constraints:
-231 <= numerator, denominator <= 231 - 1
denominator != 0
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to converting a fraction to a decimal involves performing long division by hand, digit by digit. We repeatedly find the quotient and remainder at each step, keeping track of the remainders we've seen. If a remainder repeats, the decimal part repeats from that point onward.
Here's how the algorithm would work step-by-step:
def fraction_to_recurring_decimal(numerator, denominator):
if numerator == 0:
return "0"
sign = "-" if (numerator < 0) ^ (denominator < 0) else ""
numerator = abs(numerator)
denominator = abs(denominator)
whole_number_part = numerator // denominator
remainder = numerator % denominator
if remainder == 0:
return sign + str(whole_number_part)
decimal_part = ""
remainders_seen = {}
while remainder != 0 and remainder not in remainders_seen:
# Store the current remainder and its index in decimal_part
remainders_seen[remainder] = len(decimal_part)
remainder *= 10
decimal_part += str(remainder // denominator)
remainder %= denominator
if remainder == 0:
return sign + str(whole_number_part) + "." + decimal_part
else:
# Repeating part found; insert parentheses
insert_position = remainders_seen[remainder]
decimal_part = decimal_part[:insert_position] + "(" +
decimal_part[insert_position:] + ")"
return sign + str(whole_number_part) + "." + decimal_part
To convert a fraction to a decimal, we perform long division. When the remainder repeats during division, the decimal part also repeats, indicating a recurring decimal. We use a map to detect repeating remainders, which allows us to efficiently determine the repeating part.
Here's how the algorithm would work step-by-step:
def fraction_to_recurring_decimal(numerator, denominator):
if numerator == 0:
return "0"
sign = "-" if (numerator < 0) ^ (denominator < 0) else ""
numerator = abs(numerator)
denominator = abs(denominator)
integer_part = numerator // denominator
remainder = numerator % denominator
if remainder == 0:
return sign + str(integer_part)
decimal_part = ""
remainder_map = {}
while remainder != 0:
# If the remainder repeats, we have found the repeating part
if remainder in remainder_map:
index = remainder_map[remainder]
decimal_part = decimal_part[:index] + "(" + decimal_part[index:] + ")"
break
remainder_map[remainder] = len(decimal_part)
remainder *= 10
decimal_part += str(remainder // denominator)
remainder %= denominator
return sign + str(integer_part) + "." + decimal_part
Case | How to Handle |
---|---|
Numerator is zero | Return '0' immediately to avoid division by zero errors or unnecessary calculations. |
Denominator is zero | Throw an IllegalArgumentException (or similar) as division by zero is undefined. |
Integer overflow during multiplication/division | Use long data type for intermediate calculations (numerator and remainder) to avoid overflow issues. |
Negative numerator and/or denominator | Handle signs separately and append the correct sign to the result. |
Non-terminating repeating decimal with a very long cycle | The map storing remainders and their indices should dynamically grow to accommodate long cycles, and StringBuilder's capacity should be sufficient. |
Input is MAX_INT or MIN_INT | Cast inputs to long immediately to avoid Integer.MIN_VALUE / -1 issues. |
Result is a whole number (no decimal part) | The algorithm should correctly identify that there is no fractional part and return the integer part only. |
Both numerator and denominator are MAX_INT or MIN_INT | Handle the sign and then perform the long division to avoid unexpected results. |