Fraction to Recurring Decimal (M)
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 1:
Input: numerator = 1, denominator = 2
Output: "0.5"
Example 2:
Input: numerator = 2, denominator = 1
Output: "2"
Example 3:
Input: numerator = 2, denominator = 3
Output: "0.(6)"
题意
计算一个分数表示的有理数的小数形式,若为无限循环小数,则将循环部分用括号标记。
思路
直接按照小学除法步骤进行模拟,判断出现循环的依据是计算过程中有余数出现了两次,利用Hash进行标记。
代码实现
class Solution {
public String fractionToDecimal(int numerator, int denominator) {
Map<Long, Integer> map = new HashMap<>(); // key为余数值,value为对应的小数位
StringBuilder sb = new StringBuilder();
// 先将分子分母全部转化为正数,并记录符号信息
// 因为最小负int取绝对值后会溢出,所以全用long来计算
boolean negative = numerator < 0 && denominator > 0 || numerator > 0 && denominator < 0;
long dividend = Math.abs((long) numerator), divisor = Math.abs((long) denominator);
long remainder = dividend % divisor, quotient = dividend / divisor;
sb.append(quotient); // 将整数部分存入
// 仍有余数,说明存在小数部分
if (remainder != 0) {
sb.append(".");
// 余数最终为0,说明是有限小数,不为0则需要找到无限循环小数的循环部分
while (remainder != 0) {
if (!map.containsKey(remainder)) {
map.put(remainder, sb.length());
quotient = remainder * 10 / divisor;
remainder = remainder * 10 % divisor;
sb.append(quotient);
} else {
sb.insert(map.get(remainder), "(");
sb.append(')');
break;
}
}
}
return (negative ? "-" : "") + sb.toString();
}
}