[LeetCode] 166. 分数到小数

题目描述 : https://leetcode-cn.com/problems/fraction-to-recurring-decimal/

题目描述:

给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数。

如果小数部分为循环小数,则将循环的部分括在括号内。

示例:

示例 1:

输入: numerator = 1, denominator = 2
输出: "0.5"

示例 2:

输入: numerator = 2, denominator = 1
输出: "2"

示例 3:

输入: numerator = 2, denominator = 3
输出: "0.(6)"

思路:

这种题有几种情况

  1. 正负号问题
  2. 加小数点的情况, 比如 8/ 2 不需要加小数点
  3. 小数部分,如何判断是否开始循环了

解决方法,

  1. 先判断结果的正负
  2. 直接相除, 通过余数,看能否整除
  3. 开始循环的时候, 说明之前已经出现过这个余数, 我们只要记录前面出现余数的位置,插入括号即可!

详细解释在代码里, 很好理解!

Python 用起来很爽, 但是 Java 要考虑负数转正数 possible overflow!

代码:

class Solution:
    def fractionToDecimal(self, numerator: int, denominator: int) -> str:
        if numerator == 0: return "0"
        res = []
        # 首先判断结果正负, 异或作用就是 两个数不同 为 True 即 1 ^ 0 = 1 或者 0 ^ 1 = 1
        if (numerator > 0) ^ (denominator > 0):
            res.append("-")
        numerator, denominator = abs(numerator), abs(denominator)
        # 判读到底有没有小数
        a, b = divmod(numerator, denominator)
        res.append(str(a))
        # 无小数
        if b == 0:
            return "".join(res)
        res.append(".")
        # 处理余数
        # 把所有出现过的余数记录下来
        loc = {b: len(res)}
        while b:
            b *= 10
            a, b = divmod(b, denominator)
            res.append(str(a))
            # 余数前面出现过,说明开始循环了,加括号
            if b in loc:
                res.insert(loc[b], "(")
                res.append(")")
                break
            # 在把该位置的记录下来
            loc[b] = len(res)
        return "".join(res)

posted on 2019-08-06 23:00  威行天下  阅读(287)  评论(0编辑  收藏  举报

导航