【leetcode热题】 分数到小数

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

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

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

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

示例 1:

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

示例 2:

输入:numerator = 2, denominator = 1
输出:"2"

示例 3:

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

解法一

这道题说简单的话,其实就是模拟下我们算除法的过程。

说难的话,有很多坑的地方要注意下,自己也是提交了好几次,才 AC 的,需要考虑很多东西。

首先说一下我们要模拟一下什么过程,以 20/11 为例。

第一次得到的商,就是我们的整数部分,int 间运算就可以直接取到整数部分了,记为 integer

也就是 integer = 20 / 11 = 1

然后回想一下我们用竖式计算的过程。

如下图,首先得到了商是 1,余数是 9。在程序中得到余数的话,可以用 被除数 - 商 * 除数

也就是 20 - 1 * 11 = 9

如下图,接下来我们将余数乘以 10 做为新的被除数,继续把 11 当做除数。然后得到商和新的余数。

也就是计算 90 / 11

如下图,接下来重复上边的过程,用余数乘以 10 做为新的被除数,继续把 11 当做除数。然后得到商和新的余数。

也就是计算 20 / 11

如下图,接下来继续重复上边的过程,用余数乘以 10 做为新的被除数,继续把 11 当做除数。然后得到商和新的余数。

也就是计算 90 / 11

那么什么时候结束呢?

  • 第一种情况,余数为 0,说明没有循环小数。

  • 第二种情况,一开始这里爬坑了。开始觉得只要商里边出现重复的数字(不考虑整数部分的数字,也就是上边例子的第一个 1),就可以认为出现了循环小数。

    比如上边的例子,8 第二次出现,所以到这里不再计算。而循环小数部分就是和当前数字重复的位置到当前位置的前一个,也就是 81。所以最终结果就是 1.(81)

    但提交的时候,出现了一个反例,如下图。

    虽然出现了重复的 8,但最终结果并不是 8 循环。很明显下次是 40 / 17,需要商 2。至于原因就是两次商 8 所对应的被除数并不一样,第一次是 150 ,第二次是 140

    所以为了判断是否出现循环小数,我们不应该判断是否出现了重复的商,而是应该判断是否出现了重复的被除数。

经过上边的分析,循环也很明显了。被除数除以除数,记录商。然后余数乘以 10 做为新的被除数继续除以除数。直到余数为 0 或者出现重复的被除数。

记录商的话,我们将整数部分和小数部分单独记录。因为小数部分要累积记录,一开始我用的是一个 int 去保存小数部分。比如第一个商是 1,第二个商是 2,我把之前的商乘以 10 再加上新的商。也就是 1 * 10 + 2 = 12,当第三个商 5 来的时候,就是 12 * 10 + 5 = 125,看起来很完美。

但比如上边的例子 1/17 ,小数部分第一个商是 0,第二个商是 5,如果按上边的记录方法,记录的就是 5,而不是 05。另外,如果商的部分数字过多的话,还会产生溢出,所以最终用 String 记录了商,每次将新的商加到 String 中即可。

还有一个问题就是怎么判断是否出现了重复的商?

很简单,用一个 HashMapkey 记录出现过的被除数,value 记录商出现的位置,这样当出现重复被除数的时候,通过 value 立刻知道循环的小数部分是多少。

最后一个问题,我们只考虑了正数除以正数的例子,对于正数除以负数或者负数除以负数呢?和我们在纸上算一样,先确定商的符号,然后将被除数和除数都转为正数即可。

上边的操作会带来一个问题,对于 java 而言,int 类型的话,负数的最小值是 -2147483648,正数的最大值是 2147483647,并不能把-2147483648 转成正数,至于原因的话可以参考这篇文章,补码。

溢出这个问题其实不是这个题的关键,所以我们直接用数据范围更大的 long 去存数字就可以了。

public String fractionToDecimal(int numerator, int denominator) {
    long num = numerator;
    long den = denominator;
    String sign = "";
    //确定符号
    if (num > 0 && den < 0 || num < 0 && den > 0) {
        sign = "-";
    }
    //转为正数
    num = Math.abs(num);
    den = Math.abs(den);
    //记录整数部分
    long integer = num / den;
    //计算余数
    num = num - integer * den;
    HashMap<Long, Integer> map = new HashMap<>();
    int index = 0;
    String decimal = "";//记录小数部分
    int repeatIndex = -1;//保存重复的位置
    while (num != 0) {
        num *= 10;//余数乘以 10 作为新的被除数
        if (map.containsKey(num)) {
            repeatIndex = map.get(num);
            break;
        }
        //保存被除数
        map.put(num, index);
        //保存当前的商
        long decimalPlace = num / den;
        //加到所有的商中
        decimal = decimal + decimalPlace;
        //计算新的余数
        num = num - decimalPlace * den;
        index++;
    }
    //是否存在循环小数
    if (repeatIndex != -1) {
        String dec = decimal;
        return sign + integer + "." + dec.substring(0, repeatIndex) + "(" + dec.substring(repeatIndex) + ")";
    } else {
        if (decimal == "") {
            return sign + integer;
        } else {
            return sign + integer + "." + decimal;
        }
    }
}

有人可能会问,如果数字很大,又超过了 long 怎么办,一种方案是之前写过的 29 题,因为负数存的数更多,所以我们可以把负数当做正数,正数当做负数,所有的计算都在负数范围内计算。另一种方案的话, java 其实已经提供了大数类 BigInteger 供我们使用,就不存在溢出的问题了。至于原理的话,应该和第 2 题 大数相加一样,把数字用链表去存储,这样多大的数字都能进行存储了,然后把运算法则都封装成方法即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/463102.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数字电子技术实验(五)

单选题 1.基本RS触发器&#xff08;与非门组成&#xff09;的状态是哪一个端口的状态&#xff1f; 答案&#xff1a;C 评语&#xff1a;10分 单选题 2. D触发器&#xff08;74LS 74&#xff09;状态方程的成立条件&#xff1f; A. CP端口高电平。 B. CP端口低电平。 C. C…

C#操作MySQL从入门到精通(4)——连接MySQL数据库

前言 我们创建好数据库、建立好数据库的表以后&#xff0c;我们就需要访问数据库了&#xff0c;比如将数据插入数据库的某张表中等一系列操作&#xff0c;在进行这些操作之前我们需要连接上数据库&#xff0c;本文就是详细讲解如何连接MySQL数据库的。 1、使用Navicat Premiu…

Visual Studio项目模板的创建与使用

Visual Studio项目模板的创建、使用、删除 创建模板项目模板的使用模板的删除 创建模板 点击项目&#xff0c;点击导出模板 选择你要创建哪个项目的项目模板&#xff0c;点击下一步 输入你的模板名称并添加模板说明&#xff0c;方便记忆 项目模板的使用 点击创建新项目 输入刚刚…

Linux-centos如何搭建yum源仓库

1.本地搭建&#xff08;无需连接外网&#xff09; 1.1检查网络配置&#xff0c;及网络连接 打开虚拟机&#xff0c;点击【编辑——虚拟网络编辑器】 点击【仅主机模式】查看子网段是否和局内IP匹配 进入局内&#xff0c;查看网络IP是否在你上述设置的网段内&#xff0c;如果不…

MyBatis plus自动生成代码

1.pom文件配置 <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version> </dependency> <dependency><groupId>com.baomidou</groupId>…

VLC抓取m3u8视频

前言 最近想看一些网络视频&#xff0c;但是很多时候网页上是m3u8推流的&#xff0c;如果在线看&#xff0c;速度又慢&#xff0c;所以就想下载下来&#xff0c;就想到了VLC的推流&#xff0c;转换能力&#xff0c;查阅资料&#xff0c;加上实践&#xff0c;总结心得。 设置中…

<Linux> 线程的同步与互斥

目录 前言&#xff1a; 一、资源共享问题 &#xff08;一&#xff09;多线程并发访问 &#xff08;二&#xff09;临界资源与临界区 &#xff08;三&#xff09;“锁” 是什么 二、多线程抢票场景 &#xff08;一&#xff09;并发抢票 &#xff08;二&#xff09;并发访…

flink1.18.0 自定义函数 接收row类型的参数

比如sql中某字段类型 array<row<f1 string,f2 string,f3 string,f4 bigint>> 现在需要编写 tableFunction 需要接受的参数如上 解决方案 用户定义函数|阿帕奇弗林克 --- User-defined Functions | Apache Flink

React 实现下拉刷新效果

简介 本文基于react实现下拉刷新效果&#xff0c;在下拉的时候会进入loading状态。 实现效果 效果如上图所示&#xff0c;在下拉到底部时候&#xff0c;会出现loading条&#xff0c;在处理完成后loading条消失。 具体代码 布局 & 逻辑 import {useRef, useState} from …

基于Java+Springmvc+vue+element实现高校心理健康系统详细设计和实现

基于JavaSpringmvcvueelement实现高校心理健康系统详细设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐…

Docker 笔记(五)--链接

这篇笔记记录了Docker 的Link。 官方文档&#xff1a; Legacy container links - Communication across links 目录 参考Legacy container linksConnect using network port mappingConnect with the linking systemThe importance of naming Communication across linksEnviro…

java多线程学习(二)

多线程学习&#xff08;一&#xff09;&#xff1a;http://t.csdnimg.cn/o3ygn 目录 一、线程安全 二、线程同步 三、加锁的实现方式一&#xff1a;同步代码块 四、加锁的实现方式二&#xff1a;同步方法 五、同步方法和同步代码块的比较 六、加锁的实现方式三&#xff…

zookeeper快速入门一:zookeeper安装与启动

本文是zookeeper系列之快速入门中的第一篇&#xff0c;欢迎大家观看与指出不足。 写在前面&#xff1a; 不影响教程&#xff0c;笔者安装zookeeper用的是WSL(windows下的linux子系统&#xff09;&#xff0c;当然你想直接在windows上用zookeeper也是可以的。 如果你也想用ws…

全国农产品价格分析预测可视化系统设计与实现

全国农产品价格分析预测可视化系统设计与实现 【摘要】在当今信息化社会&#xff0c;数据的可视化已成为决策和分析的重要工具。尤其是在农业领域&#xff0c;了解和预测农产品价格趋势对于农民、政府和相关企业都至关重要。为了满足这一需求&#xff0c;设计并实现了全国农产…

向量相似性度量的常用方法

向量相似性度量的常用方法 0. 引言1. 欧氏距离(Euclidean distance)2. 余弦相似度(Cosine similarity)3. 汉明距离(Hamming distance)4. 点积相似度 (Dot Product Similarity)5. 曼哈顿距离 (Manhattan Distance) 0. 引言 今天花时间学习学习向量相似性度量的常用方法&#xf…

[蓝桥杯练习题]确定字符串是否包含唯一字符/确定字符串是否是另一个的排列

确定字符串是否包含唯一字符 #include<bits/stdc.h> using namespace std; int main(){ios::sync_with_stdio(0);cin.tie(nullptr);cout.tie(nullptr);map<char,int>m;string s;cin>>s;for(int i0;i<s.size();i){if(isalpha(s[i]))s[i]tolower(s[i]);if(…

Mock.js了解(Mock就是模拟一个后端,Postman模拟前端)

JSON5 Node.js Vue CLI与Mock.js Jquery与Mock.js Mock与分页

NeRF学习——NeRF-Pytorch的源码解读

学习 github 上 NeRF 的 pytorch 实现项目&#xff08;https://github.com/yenchenlin/nerf-pytorch&#xff09;的一些笔记 1 参数 部分参数配置&#xff1a; 训练参数&#xff1a; 这段代码是在设置一些命令行参数&#xff0c;这些参数用于控制NeRF&#xff08;Neural Radi…

智慧城市与数字孪生:共创未来城市的智慧生活

目录 一、智慧城市与数字孪生的概念与特点 二、智慧城市与数字孪生共创智慧生活的路径 1、城市规划与建设的智能化 2、城市管理与服务的智慧化 3、城市安全与应急管理的智能化 三、智慧城市与数字孪生面临的挑战与对策 四、智慧城市与数字孪生的发展趋势与展望 1、技术…

redis中List和hash数据类型

list类型是用来存储多个有序的字符串的&#xff0c;列表当中的每一个字符看做一个元素&#xff0c;一个列表当中可以存储一个或者多个元素&#xff0c;redis的list支持存储2^32-1个元素。redis可以从列表的两端进行插入&#xff08;pubsh&#xff09;和弹出&#xff08;pop&…