LeetCode 题解工作台

分数到小数

给定两个整数,分别表示分数的分子 numerator 和分母 denominator ,以 字符串形式返回小数 。 如果小数部分为循环小数,则将循环的部分括在括号内。 如果存在多个答案,只需返回 任意一个 。 对于所有给定的输入, 保证 答案字符串的长度小于 10 4 。 注意 ,如果分数可以表示为…

category

3

题型

code_blocks

7

代码语言

hub

3

相关题

当前训练重点

中等 · 哈希·数学

bolt

答案摘要

我们首先判断 是否为 ,如果是,则直接返回 `"0"`。 接着我们判断 和 是否异号,如果是,则结果为负数,我们将结果的第一个字符设为 `"-"`。

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 哈希·数学 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

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

解题思路

方法一:数学 + 哈希表

我们首先判断 numeratornumerator 是否为 00,如果是,则直接返回 "0"

接着我们判断 numeratornumeratordenominatordenominator 是否异号,如果是,则结果为负数,我们将结果的第一个字符设为 "-"

然后我们将 numeratornumeratordenominatordenominator 取绝对值,分别记为 aabb。由于分子和分母的范围为 [231,2311][-2^{31}, 2^{31} - 1],直接取绝对值可能会溢出,因此我们将 aabb 都转换为长整型。

接着我们计算整数部分,即 aa 除以 bb 的整数部分,将其转换为字符串并添加到结果中。然后我们将 aa 取余 bb,记为 aa

如果 aa00,说明结果为整数,直接返回结果。

接着我们计算小数部分,我们使用哈希表 dd 记录每个余数对应的结果的长度。我们不断将 aa 乘以 1010,然后将 aa 除以 bb 的整数部分添加到结果中,然后将 aa 取余 bb,记为 aa。如果 aa00,说明结果为有限小数,直接返回结果。如果 aa 在哈希表中出现过,说明结果为循环小数,我们找到循环的起始位置,将结果插入括号中,然后返回结果。

时间复杂度 O(l)O(l),空间复杂度 O(l)O(l),其中 ll 为结果的长度,本题中 l<104l < 10^4

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
class Solution:
    def fractionToDecimal(self, numerator: int, denominator: int) -> str:
        if numerator == 0:
            return "0"
        ans = []
        neg = (numerator > 0) ^ (denominator > 0)
        if neg:
            ans.append("-")
        a, b = abs(numerator), abs(denominator)
        ans.append(str(a // b))
        a %= b
        if a == 0:
            return "".join(ans)
        ans.append(".")
        d = {}
        while a:
            d[a] = len(ans)
            a *= 10
            ans.append(str(a // b))
            a %= b
            if a in d:
                ans.insert(d[a], "(")
                ans.append(")")
                break
        return "".join(ans)
speed

复杂度分析

指标
时间complexity depends on the number of digits in the decimal expansion before repeating, and space complexity depends on the number of remainders encountered. In the worst case, the time and space complexity are both O(N), where N is the number of digits before the decimal starts repeating.
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    Check for the candidate's understanding of long division.

  • question_mark

    Evaluate their ability to track repeating decimals efficiently with hash tables.

  • question_mark

    Assess if the candidate is careful with edge cases like negative numbers and zero denominators.

warning

常见陷阱

外企场景
  • error

    Failing to correctly identify the repeating decimal pattern.

  • error

    Not handling negative numbers properly, leading to incorrect results.

  • error

    Not using a hash table efficiently, causing unnecessary recalculations of remainders.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Handle larger numbers in the numerator and denominator.

  • arrow_right_alt

    Allow more than one repeating decimal cycle (e.g., 1/7 = '0.(142857)').

  • arrow_right_alt

    Modify the problem to handle fractions where the result is an integer, avoiding decimals altogether.

help

常见问题

外企场景

分数到小数题解:哈希·数学 | LeetCode #166 中等