分数到小数

题目链接

分数到小数

题目描述

分数到小数_第1张图片

注意点

  • denominator != 0
  • 对于所有给定的输入,保证 答案字符串的长度小于 10000
  • 如果小数部分为循环小数,则将循环的部分括在括号内

解答思路

  • 本题关键是要找到循环小数的部分并将其两侧加上括号,模拟除法运算,如果某一次求模取余时得到的余数在之前的除法运算时出现过,则说明从该位置开始的小数部分开始循环了,所以需要用哈希表存储每个余数及余数出现的位置,在找到重复余数后,将重复部分的字符串放到括号中即可

代码

class Solution {
    public String fractionToDecimal(int numerator, int denominator) {
        long a = numerator, b = denominator;
        // 本身能整除
        if (a % b == 0) {
            return String.valueOf(a / b);
        }
        StringBuilder sb = new StringBuilder();
        if (a < 0 ^ b < 0) {
            sb.append('-');
        }
        a = Math.abs(a);
        b = Math.abs(b);
        sb.append(String.valueOf(a / b)).append('.');
        // 存储余数及其出现的位置
        Map<Long, Integer> map = new HashMap<>();
        a = a % b;
        while (a != 0) {
            map.put(a, sb.length());
            // 模拟求模取余
            a *= 10;
            sb.append(String.valueOf(a / b));
            a = a % b;
            // 余数之前出现过,则已找到小数循环部分
            if (map.containsKey(a)) {
                int loc = map.get(a);
                return sb.substring(0, loc) + "(" + sb.substring(loc, sb.length()) + ")";
            }
        }
        return sb.toString();
    }
}

关键点

  • 先排除掉两个数本身能除尽时的特殊情况
  • 注意分子和分母有一个值为负数时结果应该在首位加上’-’
  • 虽然分子和分母都是在Integer范围内的整数,但是相除后可能越界,所以需要先将分子和分母转换为Long类型
  • 仅将小数部分的循环部分括在括号内
  • 当进行除法运算余数重复出现时说明开始循环了

你可能感兴趣的:(算法,数据结构,算法,leetcode,java)