持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情
题目(Fraction to Recurring Decimal)
链接:https://leetcode-cn.com/problems/fraction-to-recurring-decimal
解决数:446
通过率:33.3%
标签:哈希表 数学 字符串
相关公司:goldman-sachs airbnb google
给定两个整数,分别表示分数的分子 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 - 1denominator != 0
思路
- 先全部转化成正数
- 记录余数出现的位置,如果下次再重复,则说明循环了
/**
* @param {number} numerator
* @param {number} denominator
* @return {string}
*/
var fractionToDecimal = function(numerator, denominator) {
if(numerator === '0') return '0';
let ans = '';
let map = new Map();
let a = Math.abs(numerator);
let b = Math.abs(denominator);
let c = Math.floor(a / b);// 数字比较大的时候位运算会出问题 -2147483648 和 1
let d = a % b;
if((numerator > 0 && denominator < 0) || (numerator < 0 && denominator > 0) ) {
ans = ans.concat('-')
}
ans = ans.concat(c);
if(d === 0) return ans;
ans = ans.concat('.');
while(d !== 0) {
if(map.has(d)) {
ans = insert('(',map.get(d),ans);
ans = ans.concat(')');
return ans;
}
map.set(d,ans.length);
d *= 10;
ans = ans.concat(d/b | 0);
d = d % b;
}
return ans;
}
const insert = function(str,pos,ans) {
return ans.substring(0,pos) + str + ans.substring(pos);
}
思路2
/**
* @param {number} numerator
* @param {number} denominator
* @return {string}
*/
var fractionToDecimal = function(numerator, denominator) {
// 首先,对特殊情况进行处理
if (denominator == 0) return ""; // 分母,分子为0
if (numerator == 0) return "0";
let rst = [];
if ((denominator > 0) ^ (numerator > 0)) rst.push("-"); // 商为负的情况
let denom = Math.abs(denominator); // 分子,分母化为整数
let numer = Math.abs(numerator);
// 然后,模仿除法手算过程,每次得到的商存起来(数组),余数和下一个商是对应的,所以将余数作为键存到map中,对应的值为下一个商在数组中的序号。新得到的余数*10,作为下个被除数,当新得到得余数已存在map中时,在该存在的余数对应的数组编号处插入前括号。
let quotient = Math.floor(numer / denom);
rst.push(quotient);
let remainder = numer % denom;
if (!remainder) return rst.join("");
rst.push("."); // 插入小数点
let remMap = new Map();
while (remainder && !remMap.has(remainder)) { // 小数部分
remMap.set(remainder, rst.length);
remainder *= 10;
rst.push(Math.floor(remainder / denom));
remainder %= denom;
}
if (remMap.has(remainder)) {
rst.push(")");
let index = remMap.get(remainder);
rst.splice(index, 0, "(");
}
return rst.join("");
};