力扣166(java)-分数到小数(中等)

题目:

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

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

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

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

 

示例 1:

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

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

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

提示:

-231 <= numerator, denominator <= 231 - 1
denominator != 0

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/fraction-to-recurring-decimal
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

模拟:

1.首先需要将分子分母转换成long类型。因为分子分母起初均为int类型,当numerato231 和 denominator = -1时,计算结果为231,超出 int 的范围 [-231, 231 - 1];

2.将分数计算出小数拆解成三个问题:

  • 确定小数的正负号:将分子分母相乘,如果计算结果小于0,则先往答案头部加一个 “-” 号;
  • 确定小数的小数点前面的整数:分子/分母整数相除的结果就为小数点前面的整数,整除得到的整数部分可能为0;
  • 确定小数的小数点后的有限小数或无限循环小数:模拟数学中除法的计算过程,不断对余数补0(乘10),再重新计算余数和除数的新余数
    • 如果在某一步出现分子能与分母整除,则是有限小数;
    • 一旦出现之前出现过的余数,说明产生了循环小数,则使用哈希表存储余数最早出现的位置,出现相同余数时,则将左括号插入到循环小数的开始位置,然后在循环小数结尾加上右括号,这样括号内的数即为循环小数部分。

java代码:

 1 class Solution {
 2     public String fractionToDecimal(int numerator, int denominator) {
 3         //将分子分母转换成long
 4         long a = numerator, b = denominator;
 5         //如果本身能够整除,直接返回计算结果
 6         if(a % b == 0) return String.valueOf(a / b);
 7         StringBuilder sb = new StringBuilder();
 8         //如果分子分母异号,直接追加一个负号
 9         if(a * b < 0) sb.append('-');
10         //取分子分母的绝对值
11         a = Math.abs(a);
12         b = Math.abs(b);
13         //计算小数点前面的整数
14         sb.append(String.valueOf(a/b) + ".");
15         //将余数赋值给a
16         a %= b;
17         Map<Long, Integer> map = new HashMap<>();
18         //记录当前余数的开始位置,并继续模拟除法
19         while(a != 0 && !map.containsKey(a)){
20             map.put(a, sb.length());
21             a *= 10;
22             sb.append(a / b);
23             a %= b;
24         }
25         if(a == 0) return sb.toString();
26         return sb.insert(map.get(a).intValue(), '(').append(')').toString();
27     }
28 }

 小知识:

StringBuilder insert(int offset, char c):在此序列中插入 char参数的字符串表示形式

offset 表示字符插入的位置,该位置元素(包括该位置的元素)及之后字符串往后移
例如:如果z引用当前内容为“ start ”的字符串构建器对象,那么z.insert(4, “le”)会将字符串构建器更改为包含“ starlet ”。

posted on 2022-10-04 22:01  我不想一直当菜鸟  阅读(40)  评论(0编辑  收藏  举报