166. 分数到小数
原始题目链接:https://leetcode.cn/problems/fraction-to-recurring-decimal/
给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以 字符串形式返回小数 。
如果小数部分为循环小数,则将循环的部分括在括号内。
如果存在多个答案,只需返回 任意一个 。
对于所有给定的输入,保证 答案字符串的长度小于 104 。
示例 1:
输入:numerator = 1, denominator = 2
输出:“0.5”
示例 2:
输入:numerator = 2, denominator = 1
输出:“2”
示例 3:
输入:numerator = 4, denominator = 333
输出:“0.(012)”
提示:
-231 <= numerator, denominator <= 231 - 1
denominator != 0
解题思路:
先判断分母是否为0,在判断正负号,然后判断小数是否循环。 使用一个字典来判断小数是否循环,key是余数,value是余数对除数相除的商,即要返回字符串中的数字的对应的索引位置。
代码实现:
class Solution:
def fractionToDecimal(self, numerator: int, denominator: int) -> str:
# 分母为0
if numerator == 0:
return "0"
ans = []
if (numerator > 0) ^ (denominator > 0):
ans.append("-")
numerator, denominator = abs(numerator), abs(denominator)
a, b = divmod(numerator, denominator)
ans.append(str(a))
# 余数为0,表示整除
if b == 0:
return "".join(ans)
# 不整除即有小数,加个小数点
ans.append(".")
# 用一个字典记录小数开始的位置
# key是余数,value是余数做除法后的商对应在ans中的位置
loc = {b: len(ans)}
# 处理余数
while b:
# 余数相对于除数位数不够做除法,将余数扩大一位,即乘以10
b *= 10
# a是商,b是余数,做了除法更新余数
a, b = divmod(b, denominator)
ans.append(str(a))
# 如果余数在字典中出现过了,表示开始重复循环了
# 依据题意加括号
if b in loc:
ans.insert(loc[b], "(")
ans.append(")")
break
# 记录新的余数做除法后的商对应在ans中的位置
loc[b] = len(ans)
return "".join(ans)
参考文献:
https://leetcode.cn/problems/fraction-to-recurring-decimal/solution/ji-lu-yu-shu-by-powcai/