0%

leetCode-166:Fraction to Recurring Decimal

问题描述

给定两个整数,表示被除数和除数,要求用字符串表示他们的商。如果是无限循环小数,则用 () 将循环部分包起来。题目链接:**点我**

样例输入输出

输入:numerator = 1, denominator = 2

输出:”0.5”

输入:numerator = 4, denominator = 333

输出:”0.(012)”

问题解法

此题主要是模拟除法的计算过程,对于每一轮过程,需要将余数乘10然后除以除数,与此同时,需要判断余数是否在之前的计算中出现过,如果出现,则表示这是一个无限循环小数,并且是从当前开始进行循环。

此题的另一个需要注意的地方是输入的数是 int的范围,可能存在负数,在计算过程中就可能出现超出 int 范围的数,因此需要将正两个数转成 long 类型,以方便计算,确保计算过程中不出错。代码如下

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
32
33
34
35
36
class Solution {
public String fractionToDecimal(int numerator, int denominator) {
String signStr = "";
if ((numerator < 0 && denominator > 0) || (numerator > 0 && denominator < 0)) {
signStr = "-";
}

// 考虑到 -2147483648 取绝对值后仍然为 -2147483648,此处用 long 类型表示
long divisor = Math.abs((long) numerator);
long divider = Math.abs((long) denominator);

Map<Long, Integer> map = new HashMap<>();
long intNum = divisor / divider;
long modNum = divisor % divider;
StringBuilder decimalStr = new StringBuilder();
int index = 0;
while (modNum != 0) {
if (map.containsKey(modNum)) {
int loopStartIndex = map.get(modNum);
return signStr + intNum + "." + decimalStr.substring(0, loopStartIndex) + "(" + decimalStr.substring(loopStartIndex) + ")";
}
map.put(modNum, index);
index++;
divisor = modNum * 10;
modNum = divisor % divider;
divisor = divisor / divider;
decimalStr.append(divisor);
}

if (decimalStr.length() > 0) {
return signStr + intNum + "." + decimalStr;
}

return signStr + intNum;
}
}