小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
166. 分数到小数
给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以 字符串形式返回小数 。
如果小数部分为循环小数,则将循环的部分括在括号内。
如果存在多个答案,只需返回 任意一个 。
对于所有给定的输入,保证 答案字符串的长度小于 104 。
- 示例 1:
输入:numerator = 1, denominator = 2 输出:"0.5"
- 示例 2:
输入:numerator = 2, denominator = 1 输出:"2"
- 示例 3:
输入:numerator = 2, denominator = 3 输出:"0.(6)"
- 示例 4:
输入:numerator = 4, denominator = 333 输出:"0.(012)"
- 示例 5:
输入:numerator = 1, denominator = 5 输出:"0.2"
解题思路
模拟长除法,使用map记录余数出现的位置,一旦出现相同余数,说明后面就是循环部分了,就可以添加括号了。
- 最小负数转为正数的时候会溢出,因此要使用long去接
代码
class Solution {
public String fractionToDecimal(int num, int de) {
if(num==0) return "0";
StringBuilder sb=new StringBuilder();
if(num<0^de<0)
sb.append('-');
long numL=Math.abs(Long.valueOf(num));
long deL=Math.abs(Long.valueOf(de));
sb.append(numL/deL);
long re=numL%deL;
if(re==0)
return sb.toString();
sb.append('.');
HashMap<Long,Integer> map=new HashMap<>();
while(re!=0)
{
if(map.containsKey(re))
{
sb.insert(map.get(re), "(");
sb.append(')');
return sb.toString();
}
map.put(re,sb.length());
re*=10;
sb.append(String.valueOf(re/deL));
re=re%de;
}
return sb.toString();
}
}
-
时间复杂度:O(len),其中 len 是答案字符串的长度,这道题中 len<=10000 。对于答案字符串中的每一个字符,计算时间都是 O(1)。
-
空间复杂度:O(len),其中 len 是答案字符串的长度,这道题中 len<=10000 。空间复杂度主要取决于答案字符串和哈希表,哈希表中的每个键值对所对应的下标各不相同,因此键值对的数量不会超过 len.