leetcode 166

首先考虑一下符号,如果除数*被除数<0,最后结果以"-"开头。

然后把被除数和除数都取绝对值,直接整除,如果没有余数,加上符号位就可以返回了。

如果有余数的话,把刚刚得到的整数部分加上小数点。用一个map记录余数出现的次数,直到余数=0(能除尽)或者出现重复余数(循环小数)则结束,循环小数时需要在循环的部分前后加上()。

以例子来说明,-1/3,用sb来存储最终的答案,那么首先得到符号位是负号,然后1/3=0,证数部分就是0,余数为1,那么sb=-0.1。此时余数=1,然后就进入循环,先判断余数1在不在Map里,第一轮循环肯定不在,用cnt表示每个余数出现的次数,初始cnt=1,那么首先把余数1放到map里,map.put(1,cnt++)。然后为了得到sb下一位的值,我们希望是一个0-9的数,所以把余数*10=10,再除以除数,得到3就是这轮循环的结果,余数是1,此时sb就应该加上3,新的余数是1;第二轮循环,此时余数是1,发现已经在map里了,那么证明已经找到了循环小数的部分,就是3不停循环,sb此时=-0.3,已经不需要再加新的数了,我们希望结果是-0.(3),那么需要在循环小数部分的前后加上括号,后面的括号直接加在sb的结尾,前面的括号位置是从小数点开始数,到此轮循环出现的余数在Map里对应的value位置,map里第一轮循环放进去(1,1),因此左括号放在从小数点开始的第一位,得到结果,break循环,返回。

再举个例子,比如我们希望得到的结果是0.2(6),那么反向构造被除数和除数,应该是4/15,首先得到符号位和整数部分为0,然后余数为4,第一轮循环,先把(4,1)放入map,然后4*10/15=2余10,结果加2=0.2;第二轮循环,先把(10,2)放入map,然后10*10/15=6余10,结果加6=0.26;第三轮循环,此时余数为10,发现map里已经存在,说明找到了循环小数的部分,把10对应的value拿出来是2,说明左括号应该加在小数点开始第2位,右括号在最后一位,于是得到答案为0.2(6)

class Solution {
    public String fractionToDecimal(int numerator, int denominator) {
        StringBuilder sb = new StringBuilder();
        long nn = (long) numerator;
        long dd = (long) denominator;
        if (nn * dd < 0) {
            sb.append("-");
        }
        nn = Math.abs(nn);
        dd = Math.abs(dd);
        long intPart = nn / dd;
        long left = nn % dd;
        sb.append(intPart);

        if (left == 0) {
            return sb.toString();
        }
        Map<Long, Integer> map = new HashMap<>();
        int cnt = 1;
        sb.append(".");
        while (left != 0) {
            if (map.containsKey(left)) {
                int dot = sb.indexOf(".");
                sb.insert(dot + map.get(left), "(");
                sb.append(")");
                break;
            } else {
                map.put(left, cnt++);
                left *= 10;
                nn = left / dd;
                left = left % dd;
                sb.append(nn);

            }
        }


        return sb.toString();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值