leetcode 【中级】分数到小数

题干

给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数。

如果小数部分为循环小数,则将循环的部分括在括号内。

示例 1:

输入: numerator = 1, denominator = 2
输出: "0.5"

示例 2:

输入: numerator = 2, denominator = 1
输出: "2"

示例 3:

输入: numerator = 2, denominator = 3
输出: "0.(6)"

想法

其实我们仔细回想一下我们人类计算小数的方法,就是每一位用除数除以被除数,然后将余数×10作为被除数,如此往复。
于是我的代码也是这个思路
只是有几个问题:
如果有溢出怎么办?
最简单的我们用long来玩儿,就不管溢出
如何判断是有循环的?
其实是这样一个道理,因为除数不变,如果被除数出现了之前出现过的数,那就会出现循环。
再两个重复之间的数作为循环体。
我的代码写的十分详细,直接看就行

Java代码

public class Solution {
    public String fractionToDecimal(int numerator, int denominator) {
        if(numerator==0) {return "0";}//被除数为0的情况
       if(denominator==0){return String.valueOf(Integer.MAX_VALUE);}//除数为0的情况
        HashMap<Long,Integer> map= new HashMap<>();//用hashmap来存这个数在小数点后的位置和值
        List<Long> number=new ArrayList<>();//list来存整个数的每位
        int index=0;//现在进行到哪个位置
        int beginIndex=-1;//循环开始的位置
       StringBuilder builder = new StringBuilder();
        Long num=(long)numerator;//转换成long,下同
        Long denum=(long)denominator;
        if((num<0&&denum>0)||(num>0&&denum<0)){//如果异号,开头加负号
            builder.append('-');}
                num=Math.abs(num);//都取成正的,下同
                denum=Math.abs(denum);
            
            Long val=num/denum;//这一位的数
            builder.append(String.valueOf(val));//第一位直接加进去,其实可以不要list直接加sb
            num=(num%denum)*10;//余数×10作为被除数
            
            while(num!=0){
                if(!map.containsKey(num)){//如果hashmap里没有,证明没有出现过
                    map.put(num,index++);//加到hashmap
                    val=num/denum;
                    number.add(val);
                    num=(num%denum)*10;
                }else{
                    beginIndex=map.get(num);//有的话,在list里找到这个数的位置,作为循环开始的位置
                    break;
                }
            }
            for(int i=0;i<index;i++){
                if(i==0) {builder.append('.');}//加小数点
                if(i==beginIndex) {builder.append('(');}//循环体
                builder.append(number.get(i));//将list的每一位加到sb
            }
            if(beginIndex!=-1){
                builder.append(')');//循环结束,最后补一个)
            }
      return builder.toString();  }
    }

优化
其实list可以不要,hashmap也可以使用有序的,以下是几个更好的代码(可读性可能没那么好

public String fractionToDecimal(int numerator, int denominator) {
    if (numerator == 0) {
        return "0";
    }
    StringBuilder fraction = new StringBuilder();
    // If either one is negative (not both)
    if (numerator < 0 ^ denominator < 0) {
        fraction.append("-");
    }
    // Convert to Long or else abs(-2147483648) overflows
    long dividend = Math.abs(Long.valueOf(numerator));
    long divisor = Math.abs(Long.valueOf(denominator));
    fraction.append(String.valueOf(dividend / divisor));
    long remainder = dividend % divisor;
    if (remainder == 0) {
        return fraction.toString();
    }
    fraction.append(".");
    Map<Long, Integer> map = new HashMap<>();
    while (remainder != 0) {
        if (map.containsKey(remainder)) {
            fraction.insert(map.get(remainder), "(");
            fraction.append(")");
            break;
        }
        map.put(remainder, fraction.length());
        remainder *= 10;
        fraction.append(String.valueOf(remainder / divisor));
        remainder %= divisor;
    }
    return fraction.toString();
}

此代码摘自https://blog.csdn.net/xushiyu1996818/article/details/86675730

class Solution {
    public String fractionToDecimal(int numerator, int denominator) {
        long lnumerator = Math.abs((long)numerator);
        long ldenominator = Math.abs((long)denominator);
        long r = lnumerator % ldenominator;
        StringBuilder res = 
            new StringBuilder(((numerator != 0) && ((numerator > 0) ^ (denominator > 0)))? "-" : "");
        res.append((lnumerator / ldenominator));

        if(r == 0) return res.toString();
        
        HashMap<Long, Integer> remains = new HashMap();
        StringBuilder fraction = new StringBuilder();
        while(r > 0 && !remains.containsKey(r)){
            remains.put(r, fraction.length());
            r *= 10;
            fraction.append(r / ldenominator);
            r = r % ldenominator;
        }
    
        if(remains.containsKey(r)){
           int recur_pos = remains.get(r);
           fraction.insert((int)remains.get(r), '(').append(')');
        }
        return res.append('.').append(fraction).toString();
    }
}

此代码摘自leetcode官网

总结

题还是蛮有意思的,就是sima leetcode现在在线编译如果编译不通过不报错误位置了…

差评!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值