​LeetCode刷题实战166:分数到小数

程序IT圈

共 2906字,需浏览 6分钟

 ·

2021-01-28 14:17

算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !

今天和大家聊的问题叫做 分数到小数  ,我们先来看题面:
https://leetcode-cn.com/problems/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.


If multiple answers are possible, return any of them.


It is guaranteed that the length of the answer string is less than 104 for all the given inputs.

题意


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

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

如果存在多个答案,只需返回 任意一个 。

对于所有给定的输入,保证 答案字符串的长度小于 104  。


样例

示例 1

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

输入:numerator = 2, denominator = 1
输出:"2"
示例 3

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

输入:numerator = 4, denominator = 333
输出:"0.(012)"
示例 5

输入:numerator = 1, denominator = 5
输出:"0.2"



解题

https://blog.csdn.net/tiaochewang219/article/details/85641972

思路:

网上对于这道题的解答,思路上大同小异
1.首先符号位单独拿出来判断
2.整数部分单独计算(通过判断是否能整除)
3.整除则可以返回结果了,不能整数则追加“.”
4.小数部分通过循环来计算,只要余数不为0,就通过扩大十倍再与除数相除,这里需要通过一个Map来记录余数,因为循环小数的特征是出现余数相同的结果,当碰到存储过得余数时说明产生循环了,在那个位置添加一个“(”即可,再在结果追加一个“)”
5.下面的代码并不是最优的,一是:可以将循环追加小数的那一部分改为,通过记录循环产生位置,向其中添加括号,二是将有序Map替换为无序HashMap


public static String fractionToDecimal(int numerator, int denominator) {
    
    //特殊情况单独处理
    if(numerator==0) {
      return "0";
    }
    //符号位单独判断-1为负,0为正
    int flag = (numerator^denominator)>>31;
        //整数部分的值单独求
    long num = Math.abs((long)numerator),den = Math.abs((long)denominator);
    long Int = num/den;
    long remainder = num%den;
    StringBuffer res = new StringBuffer();
    res.append(flag==-1?"-"+Int:Int);
    if(remainder==0) {
      //可以整除
      return res.toString();
    }
    //不能整除,先加一个小数点
    res.append(".");
    //小数部分单独处理,有能除尽和循环两种情况
    //是否循环通过Map对应位置来判断
    //出现循环应当是余数出现和之前相同了
    Map map = new LinkedHashMap();
    long div = 0;
    while(remainder!=0) {
      remainder *= 10;
      //获取商
      div = remainder/den;
      map.put(remainder/10,div); //将余数和商存入
      remainder %= den;
      if(map.containsKey(remainder)) {
        //出现循环了,将所有循环数括起来
        //注意此处应当是从循环的位置括起来,而不是开头
        
        int fla = 0;
        for(Long key:map.keySet()) {
          if(fla==0&&key!=remainder) {
            res.append(map.get(key));
          }
          if(key==remainder) {
            fla = 1;res.append("(");
          }
          if(fla==1) {
            res.append(map.get(key));
          }
        }
        res.append(")");
        return res.toString();
      }
    }
    for(Long key:map.keySet()) {
      res.append(map.get(key));
    }
    return res.toString();
    }


好了,今天的文章就到这里,如果觉得有所收获,请顺手点个在看或者转发吧,你们的支持是我最大的动力 。

上期推文:

LeetCode1-160题汇总,希望对你有点帮助!
LeetCode刷题实战161:相隔为1的编辑距离
LeetCode刷题实战162:寻找峰值
LeetCode刷题实战163:缺失的区间
LeetCode刷题实战164:最大间距
LeetCode刷题实战165:比较版本号


浏览 30
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报