166. Fraction to Recurring Decimal
Leetcode Hash Table MathGiven 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"
Input: numerator = 2, denominator = 1
Output: "2"
Example 3:
Input: numerator = 2, denominator = 3
Output: "0.(6)"
分析¶
这道题目涉及基本的数学,难点在于如何判断数字重复以及细节的处理。首先要注意正负号、0这样的细节,然后考虑到整数可能越界,所以统一转换为长整型long。判断数字重复关键在于判断余数的重复,所以我们可以将余数和余数的位置放在哈希表中,当余数重复时,确定重复区间,加上括号
public String fractionToDecimal(int numerator, int denominator) {
// 处理0
if (numerator == 0) return "0";
StringBuilder sb = new StringBuilder();
HashMap<Long, Integer> map = new HashMap<>();
// 处理负数
boolean isPositive = numerator < 0 == denominator < 0;
if (!isPositive) sb.append("-");
long numeratorLong = Math.abs((long) numerator);
long denominatorLong = Math.abs((long) denominator);
// 整数部分
sb.append(numeratorLong / denominatorLong);
long reminder = numeratorLong % denominatorLong;
if (reminder == 0) return sb.toString();
// 小数部分
sb.append(".");
int index = sb.length();
while (reminder != 0) {
if (!map.containsKey(reminder)) { // 放入分子和分子所在的位置
map.put(reminder, index++);
} else {
// 发现重复,在合适的位置加入括号, 并结束
sb.insert(map.get(reminder), "(");
sb.append(')');
break;
}
// 添加商
reminder *= 10;
sb.append(reminder / denominatorLong);
// 更新余数
reminder %= denominatorLong;
} // end while
return sb.toString();
}