Sunday, September 6, 2015

Leetcode : 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)".
这个题目不是考的算法题,而是考各种corner case 处理以及编程能力,这个题目里面的corner case 超级多, 1. 可能存在溢出,所有类型的数先转化成long,包括, 除数,被除数以及余数 2. corner case : 当INT_MIN / (-1)的时候结果是越界的,所以必然要特殊处理 3. 可能最后是正数,也可能是负数,所以先全部转化成正数,最后再处理符号。
对于recursive的那部分,怎么得到呢? 要发现,recursive的部分是余数出现重复的情况下发生的,所以我们可以记录每次余数的情况,用一个hashmap,记录余数和其对应的在rst里第一次出现的商的index就可以了。 
class Solution {
public:
    string fractionToDecimal(int numerator, int denominator) {
        string rst = "";
        //corner case
        long a = numerator;
        long b = denominator;
        a = abs(a);
        b = abs(b);
        if (numerator == INT_MIN && denominator == -1) {
            return to_string(a);
        }
        //case 1:
        if (numerator%denominator == 0) {
            rst = to_string(numerator/denominator);
            return rst;
        }
        //case 2
        //get integer part
        int integer = a / b;
        rst = to_string(integer) + '.';
        long remainder1= a % b;
        unordered_map<int, int> rmap;
        while (remainder1) {
            if (rmap.find(remainder1) == rmap.end()) {
                rmap[remainder1] = rst.size()-1;
                rst += to_string(remainder1*10/b);
            } else {
                string tmp = rst.substr(0, rmap[remainder1]+1);
                tmp += '(' + rst.substr(rmap[remainder1]+1) + ')';
                rst = tmp;
                break;
            }
            remainder1 = (remainder1 * 10) % b;
        }
        return ((numerator < 0) ^ (denominator < 0)) ? ("-"+rst) : rst;
    }
};

No comments:

Post a Comment