题目:
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.
For example,
- Given numerator = 1, denominator = 2, return "0.5".
- Given numerator = 2, denominator = 1, return "2".
- Given numerator = 2, denominator = 3, return "0.(6)".
题意:
分数转换为循环小数,给定两个整数,分别代表分数的分子和分母,以字符串的格式返回分数值。如果分数结果的部分是重复的,将重复部分括在括号里。
思路:
按照简单两数相除步骤进行操作。将每一步的结果组拼成返回字符串。主要需要注意的是重复部分的处理,以及处理正负号时所产生的溢出问题。
官方思路:
0.16 6 ) 1.00 0 1 0 <-- Remainder=1, mark 1 as seen at position=0. - 6 40 <-- Remainder=4, mark 4 as seen at position=1. - 36 4 <-- Remainder=4 was seen before at position=1, so the fractional part which is 16 starts repeating at position=1 => 1(6).使用map记录每次操作之后的余数和对应的下标,HashMap的<key, value>分别对应<当前余数, 对应结果的下标>,当出现重复值的时候,可以通过对应下标寻找到重复部分。
代码:java版 :5ms
public class Solution { public String fractionToDecimal(int numerator, int denominator) { if(numerator == 0) return "0"; if(denominator == 0) return ""; String result = ""; //判断结果是否为负数,加负号 if((numerator<0) ^ (denominator<0)) result += "-"; //保证分子分母都为正数,防止取绝对值溢出,先将int转换为long,再取绝对值 long num = numerator; long den = denominator; num = Math.abs(num); den = Math.abs(den); //得到结果的整数部分 long numInt = num/den; result += String.valueOf(numInt); //判断是否能整除,如果能,则直接返回结果 long numres = (num%den)*10; if(numres==0) return result; //结果的小数部分 HashMap<Long, Integer> map = new HashMap<Long, Integer>(); result += "."; while(numres!=0){ //判断map中是否出现过该余数,如果出现过则开始循环 if(map.containsKey(numres)){ int beg = map.get(numres); //循环体开始的位置 String part1 = result.substring(0, beg); String part2 = result.substring(beg, result.length()); result = part1 + "(" + part2 + ")"; return result; } //继续下除 map.put(numres, result.length()); numInt = numres / den; result += String.valueOf(numInt); numres = (numres%den) * 10; } return result; } }C++版:0ms
class Solution { public: string fractionToDecimal(int numerator, int denominator) { if(numerator==0) return "0"; if(denominator==0) return ""; string res; //处理结果是否是负数 if((numerator<0) ^ (denominator<0)) res += "-"; //将分子分母都转换为正数,先转化为long型,防止取绝对值时溢出 long num = numerator; long den = denominator; num = abs(num); den = abs(den); //整除部分 res += to_string(num/den); //判断是否整除是否有小数部分,没有就返回 if(num%den == 0) return res; //处理小数部分 res += '.'; unordered_map<int, int> map; for(long re=num%den; re; re %= den){ if(map.count(re)>0){ //判断是否出现重复元素 res.insert(map[re], 1, '('); //为重复部分添加括号 res += ')'; break; } //记住该余数当前位置 map[re] = res.size(); re *= 10; res += to_string(re/den); //将每一位整除部分添加到返回字符串中。 } return res; } };