指尖劃過的軌跡,藏着最細膩的答案~

題目:

給定兩個整數,分別表示分數的分子 numerator 和分母 denominator,以 字符串形式返回小數

如果小數部分為循環小數,則將循環的部分括在括號內。

如果存在多個答案,只需返回 任意一個

對於所有給定的輸入,保證 答案字符串的長度小於 $10^4$

示例 1:

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

示例 2:

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

示例 3:

輸入:numerator = 4, denominator = 333
輸出:"0.(012)"

提示:

  • $-2^{31} \leq numerator, denominator \leq 2^{31} - 1$
  • $denominator \neq 0$

分析:

本題我們首先需要模擬長除法即可,假設商為q,餘數為r,則除法運算如下:$\frac{a}{b} = q...r$,將q拼接如答案,接下來將$\frac{r * 10}{b} = q...r1, r = r1$,根據上面公式,直到:

  • r == 0表示除盡;
  • 循環小數:怎樣判斷循環部分呢,我們可以使用哈希表來記錄,keyrvalue下標,在再次出現r時,説明有循環,將r_to_pos[r]到當前下標使用括號括起來。

AC代碼:

class Solution {
public:
    string fractionToDecimal(int numerator, int denominator) {
        long long a = numerator, b = denominator;
        string sign = a * b < 0 ? "-" : "";
        a = abs(a);
        b = abs(b);

        long long q = a / b, r = a % b;
        if (r == 0) {
            return sign + to_string(q);
        }

        string ans = sign + to_string(q) + ".";
        unordered_map<long long, int> r_to_pos = {{r, ans.size()}};
        while(r) {
            r *= 10;
            q = r / b;
            r %= b;
            ans += '0' + q;
            if (r_to_pos.contains(r)) {
                int poc = r_to_pos[r];
                return ans.substr(0, poc) + "(" + ans.substr(poc) + ")"; 
            }
            r_to_pos[r] = ans.size();
        }

        return ans;
    }
};