LeetCode166. 分數到小數
阿新 • • 發佈:2020-08-06
要判斷是否會出現無限迴圈小數,就需要找迴圈節。
如果出現了迴圈節,會出現這樣一種情況:被除數除以除數的商,在之前已經出現過了,比如2 / 3,2比3小,借位,20 / 3 = 6 ... 2, 然後商又是6,6在之前出現過了,所以我們知道迴圈節就是6。
最終結果就是0.(6)。
要記錄之前已經出現過的商,我們就需要一個雜湊表記錄之前出現過的商,我們可以不斷做除法,直到整除或者出現迴圈節。
這道題測試用例有可能numerator是-2147483648(-231),而denominator是-1,這樣商就是2147483648(231),而int的最大值是2^31-1,因此可能會爆int,所以我們用long long來儲存中間計算結果。
程式碼如下:
class Solution { public: string fractionToDecimal(int numerator, int denominator) { typedef long long LL; LL x = numerator, y = denominator; if(x % y == 0) { //如果整除,直接返回結果 return to_string(x / y); } string res; if((x < 0) ^ (y < 0)) { //如果x和y中有且僅有1個是負數,則最終的商是負數 res += '-'; } x = abs(x), y = abs(y); res += to_string(x / y) + '.'; //計算出整數部分,不要忘了加上小數點 x %= y; unordered_map<LL, int> hash; //雜湊表記錄當前的商在res字串中出現的位置,這是為了我們之後判斷重複和擷取迴圈節 while(x != 0) { hash[x] = res.size(); //記錄下當前這個商在res中的位置,方便之後根據res的下標擷取迴圈節 x *= 10; //根據除法規則,被除數比除數小,向低位借位 res += to_string(x / y); x %= y; if(hash.count(x) != 0) { //出現重複的商,說明找到了迴圈節,把迴圈節加上括號 res = res.substr(0, hash[x]) + '(' + res.substr(hash[x]) + ')'; //res.substr(0, hash[x])是不迴圈部分,加上帶括號的迴圈節,就是最終答案 break; } } return res; } };