题目链接:Fraction to Recurring Decimal
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.
For example,
- Given numerator = 1, denominator = 2, return “0.5”.
- Given numerator = 2, denominator = 1, return “2”.
- Given numerator = 2, denominator = 3, return “0.(6)”.
这道题的要求是将分数转化成循环小数。
模拟除法的过程,直到没有余数或者余数重复。不过要注意以下2个问题:
- 去掉分子分母符号的时候,由于数据有-2147483648,转化成正数可能溢出,因此需要采用long long类型;
- 如果余数没重复,在map中记录对应位置,便于发现是循环小数时加入左括号‘(’.
时间复杂度:O(n)
空间复杂度:O(n)
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
37
38
39
40
41
42
43
44
45
46
47
48
class Solution
{
public:
string fractionToDecimal(int numerator, int denominator)
{
// 分子为0
if(numerator == 0)
return "0";
string res = "";
// 记录符号
if(numerator < 0 ^ denominator < 0)
res += "-";
// 去掉分子分母符号,存在-2147483648,因此要用long long
long long n = abs((long long)numerator);
long long d = abs((long long)denominator);
// 记录整数部分
res += to_string(n / d);
// 整除,直接返回
if(n % d == 0)
return res;
// 记录小数点‘.’
res += '.';
unordered_map<int, int> map;
// 模拟除法过程
for(long long r = n % d; r > 0; r %= d)
{
// 余数出现重复,说明生成循环小数
if(map.find(r) != map.end())
{
res.insert(map[r], 1, '(');
res += ")";
break;
}
// 余数没重复,在map中记录对应位置
// 便于循环小数时加入左括号‘(’
map[r] = res.size();
// 补一个0
r *= 10;
// 记录商,即下一位小数
res += to_string(r / d);
}
return res;
}
};