Middle-题目128: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)”.
题目大意:
把一个分数转换成小数,如果是循环小数,则用括号把循环节扩起来,输出对应的字符串。
题目分析:
就是模拟竖式除法,每一步迭代都记录下商和余数,用string记录下每一步的商,用一个HashMap记录下<余数,对应商的下标>。如果出现余数为0,则是有限小数,直接输出string即可,如果找到一个在HashMap中存在的余数,则说明发现了循环节,到HashMap中get一下就知道了循环节的开始点,这样也就结束了循环。
源码:(language:java)

public class Solution {
    public String fractionToDecimal(int numerator, int denominator) {
        if (numerator == 0) return "0";
        if (denominator == 0) return "";

        String ans = "";

        //如果结果为负数
        if ((numerator < 0) ^ (denominator < 0)) {
            ans += "-";
        }

        //下面要把两个数都转为正数,为避免溢出,int转为long
        long num = numerator, den = denominator;
        num = Math.abs(num);
        den = Math.abs(den);

        //结果的整数部分
        long res = num / den;
        ans += String.valueOf(res);

        //如果能够整除,返回结果
        long rem = (num % den) * 10;
        if (rem == 0) return ans;

        //结果的小数部分
        HashMap<Long, Integer> map = new HashMap<Long, Integer>();
        ans += ".";
        while (rem != 0) {
            //如果前面已经出现过该余数,那么将会开始循环
            if (map.containsKey(rem)) {
                int beg = map.get(rem); //循环体开始的位置
                String part1 = ans.substring(0, beg);
                String part2 = ans.substring(beg, ans.length());
                ans = part1 + "(" + part2 + ")";
                return ans;
            }

            //继续往下除
            map.put(rem, ans.length());
            res = rem / den;
            ans += String.valueOf(res);
            rem = (rem % den) * 10;
        }

        return ans;
    }
}

成绩:
5ms,beats 19.25%,众数4ms,59.22%
Cmershen的碎碎念:
本题乃Middle难度中ac率最低一题,但原理也不是很复杂,而是难在各种奇奇怪怪的边界情况,Leetcode的test case很多都侧重于一些特殊情况(这适合面试题,锻炼严谨的思维)而传统的oj题及赛题则更多侧重于大数据量下会不会tle。

你可能感兴趣的:(Middle-题目128:166. Fraction to Recurring Decimal)