leetcode_166 分数到小数

235 阅读1分钟

要求

给定两个整数,分别表示分数的分子 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"

提示:

  • -231 <= numerator, denominator <= 231 - 1
  • denominator != 0

核心代码

class Solution:
    def fractionToDecimal(self, numerator: int, denominator: int) -> str:
        n,remainder = divmod(abs(numerator),abs(denominator))
        sign = "-" if numerator * denominator < 0 else ""
        fraction = [sign + str(n)]
        if remainder == 0:
            return "".join(fraction)
        fraction.append(".")
        dic = {}
        while remainder != 0:
            # 出现过,则说明进入了循环
            if remainder in dic:
                fraction.insert(dic[remainder],"(")
                fraction.append(")")
                break
            dic[remainder] = len(fraction)
            n,remainder = divmod(remainder * 10,abs(denominator))
            fraction.append(str(n))
        return "".join(fraction)

image.png

解题思路:使用divmod获取商和余数. 然后通过余数求小数.不断将余数 * 10, 再次调用divmod, 则算出来的商就是小数.如果重复出现小数, 则说明为循环.我们使用字典进行存储每一次的除数的结果长度,当我们再次遇到这个除数的时候,说明一定是循环了,可以通过之前的记录的位置直接插入"(",在最后补上")",就是循环的。