1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Solution {
public String fractionToDecimal(int numerator, int denominator) {
if (numerator == 0) {
return "0";
}
StringBuilder ans = new StringBuilder();
if ((numerator < 0) == (denominator > 0)) {
ans.append("-");
}
long dividend = Math.abs(Long.valueOf(numerator));
long divisor = Math.abs(Long.valueOf(denominator));
long remainder = dividend % divisor;
ans.append(dividend / divisor);
if (remainder == 0) {
return ans.toString();
}

ans.append(".");
Map<Long, Integer> visited = new HashMap<>();
while (remainder != 0 && !visited.containsKey(remainder)) {
visited.put(remainder, ans.length());
remainder *= 10;
ans.append(remainder / divisor);
remainder %= divisor;
}
if (remainder != 0) {
ans = ans.insert(visited.get(remainder), "(").append(")");
}
return ans.toString();
}
}

需要注意的就是overflow, 因此我们用long. 比如-1除以Integer.MIN_VALUE. 还有就是记录小数循环的开始是哪里, 结尾是哪里. 我们通过判断remainder是否之前出现来判断. 小数的每一位对应着一个remainder. 如果某个位置的remainder发现之前出现过, 此时就可以停止了. 我们在之前出现的位置上insert一个(. 该位置以及之后的字符都会往后移动一位来给这个新被添加进来的(腾位置.