166. Fraction to Recurring Decimal

題目

Given two integers representing the numerator and denominator of a fraction, return the fraction in string format.

If the fractional part is repeating, enclose the repeating part in parentheses.

For example,

  • Given numerator = 1, denominator = 2, return "0.5".
  • Given numerator = 2, denominator = 1, return "2".
  • Given numerator = 2, denominator = 3, return "0.(6)".
分析

計算整數除法,要求循環的小數位用括號括起來,最初打算保存小數,並利用int [10]的數組保存每個值出現的位置,有重複則說明循環,加入括號即可,但是發現有些情況,比如1/333,會出現0.003003的循環,因此小數的循環不是根據商的重複出現而定,而是餘數的重複出現決定的,參考0ms C++ Solution with Detailed Explanations 的思想進行修改,利用map保存<餘數,下標>,當餘數重複出現時,只需在上次出現位置之前插入左括號,在當前末尾加入右括號即可。

class Solution {
public:
    string fractionToDecimal(int numerator, int denominator) {
        long num=numerator, den=denominator;
        string res;
        if(!num)
            return "0";
        if(num<0^den<0)//如果num和den其中一個爲負數,則需要在結果前面加上負號
            res+="-";
        num=num<0?num*=-1:num;//將負值轉換成正數
        den=den<0?den*=-1:den;
        long inter=num/den;//保存整數部分
        res+=to_string(inter);//結果加入整數部分
        num=num%den;//根據餘數計算小數部分的除法
        if(!num)//餘數爲0則整除,直接返回
            return res;
        res+=".";//否則加入小數點並餘數*10進行借位除法
        num*=10;
        unordered_map<long,long> map;//用map保存小數除法中的被除數,循環的條件是出現重複的被除數而不是通過重複的商判斷
        while(num){
            long temp=num/den;
            if(map.find(num)!=map.end()){//如果出現了重複的被除數,則下一步一定會循環,所以在上次被除數出現的位置之前插入左括號(,並在末尾插入右括號)
                res.insert(map[num],1,'(');
                res+=")";
                return res;
            }
            map[num]=res.size();//被除數不重複時,令map保存當前被除數的商在res中的下標位置,由於res還未壓入商,故該下標位置爲res.size()
            res+=to_string(temp);
            num%=den;//取餘數,乘10,繼續除法運算
            num*=10;
        }
        return res;
    }
};


發佈了180 篇原創文章 · 獲贊 15 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章