LeetCode Top Interview Questions 166. Fraction to Recurring Decimal (Java版; Medium)

welcome to my blog

LeetCode Top Interview Questions 166. Fraction to Recurring Decimal (Java版; Medium)

题目描述
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.

Example 1:

Input: numerator = 1, denominator = 2
Output: "0.5"
Example 2:

Input: numerator = 2, denominator = 1
Output: "2"
Example 3:

Input: numerator = 2, denominator = 3
Output: "0.(6)"
第一次做; 核心: 除式的计算流程; 边界情况:1)分子为0, 2)有一个数是-2147483648; 细节:注意区分全局的余数和局部的余数, 哈希表中记录的是局部的余数; 借助异或判断符号
/*
面试的时候出这道题需要主动问面试官, 除数为0时返回"false denominator"是否可以, 主动沟通
核心: 规范化除式计算的流程, 动手写一写2/3, 11/100
*/
class Solution {
    public String fractionToDecimal(int numerator, int denominator) {
        //edge
        if (numerator == 0)
            return "0";
        //存储结果的容器
        StringBuilder res = new StringBuilder();
        //判断正负; 细节运算优先级
        res.append((numerator > 0) ^ (denominator > 0) ? "-" : "");
        //主体计算流程
        /*
        将两个数都转成正数
        本来以为单独处理-2147483648/-1就可以了, 不用再转成long类型, 看了下面这个例子, 发现只要出现-2147483648就得变成long类型
        -1
        -2147483648
        */
        long nu = Math.abs((long)numerator);
        long de = Math.abs((long)denominator);
        //整数部分
        res.append(nu / de);
        nu = nu % de;
        if (nu == 0)
            return res.toString();
        //小数部分
        //先添加小数点
        res.append(".");
        //记录小数出现的位置
        HashMap<Long, Integer> map = new HashMap<>();
        //核心
        map.put(nu, res.length());
        //当余数不为0时; 不为0的余数将作为下一轮的被除数(分子)
        //核心: 什么时候检查余数是否出现过?
        while (nu != 0) {
            //核心: 借位, 也就是余数乘10; 本质上还是要规范化除式的计算流程, 动手写一写2/3, 11/100
            nu = nu * 10;
            res.append(nu / de);
            //当前的余数, 并不是全局的余数
            nu = nu % de;
            //检查全局的余数是否出现过
            if (map.containsKey(nu)) {
                //在第一次出现的位置的后面加入左括号
                res.insert(map.get(nu), "(");
                //在当前的末尾加入右括号
                res.append(")");
                break;
            }
            //res.length()指向res末尾的下一个位置
            map.put(nu, res.length());
        }
        return res.toString();
    }
}
LeetCode题解, 最优解
public class Solution {
    public String fractionToDecimal(int numerator, int denominator) {
        if (numerator == 0) {
            return "0";
        }
        StringBuilder res = new StringBuilder();
        // "+" or "-"
        res.append(((numerator > 0) ^ (denominator > 0)) ? "-" : "");
        long num = Math.abs((long)numerator);
        long den = Math.abs((long)denominator);
        
        // integral part
        res.append(num / den);
        num %= den;
        if (num == 0) {
            return res.toString();
        }
        
        // fractional part
        res.append(".");
        HashMap<Long, Integer> map = new HashMap<Long, Integer>();
        map.put(num, res.length());
        while (num != 0) {
            num *= 10;
            res.append(num / den);
            num %= den;
            if (map.containsKey(num)) {
                int index = map.get(num);
                res.insert(index, "(");
                res.append(")");
                break;
            }
            else {
                map.put(num, res.length());
            }
        }
        return res.toString();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值