力扣29(java)-两数相除(中等)
题目:
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
示例 1:
输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = truncate(3.33333..) = truncate(3) = 3
示例 2:
输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = truncate(-2.33333..) = -2
提示:
- 被除数和除数均为 32 位有符号整数。
- 除数不为 0。
- 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/divide-two-integers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:
参考各位大佬是解题思路,这里记录一下
运用的是【翻倍循环相减】法,即对除数divisor不断翻倍,找到最接近且小于被除数dividend的最大除数,然后让当前被除数减去最大除数并记录当前倍数,然后对剩余的被除数不断重复以上的操作,直至当前被除数小于除数,所有倍数求和即为商quotient。
例如:
①23 / 3
1.计算3的2x的最大值(不超过23),对3不断的翻倍,3-->6-->12-->24,此时的24超过23,即用23-12 = 11,11作为新的被除数,3 * 2 2 = 12;
2.计算3的2x的最大值(不超过11),对3不断的翻倍,3-->6-->12,此时的11超过6,即用11-6 = 5,5作为新的被除数,3 * 2 1 = 6;
3.计算3的2x的最大值(不超过5),对3不断的翻倍,3-->6,此时的6超过5,即用6-5 = 1,1作为新的被除数,3 * 2 0 = 3;
4.新的被除数1已经小于3了,计算结束,商为22+21+20=7,即可得知23 / 3 = 7(省略小数部分);
②97 / 5
1.计算5的2x的最大值(不超过97),对5不断的翻倍,5-->10-->20-->40-->80-->160,此时的160超过97,即用97-80 = 17,17作为新的被除数,5 * 2 4 = 80;
2.计算5的2x的最大值(不超过17),对5不断的翻倍,5-->10-->20,此时的20超过17,即用17-10 = 7,7作为新的被除数,5 * 2 1 = 10;
3.计算5的2x的最大值(不超过7),对5不断的翻倍,5-->10,此时的10超过7,即用7-5 = 2,2作为新的被除数,5 * 2 0 = 5;
4.新的被除数2已经小于5了,计算结束,商为24 + 21+20=19,即可得知97 / 5 = 19(省略小数部分);
再看题目结合三个提示部分,翻译过来即为:
1.不能使用long;
2.不能使用乘法、除法和 mod 运算符;
3.考虑溢出问题。
首先不使用long:在32位系统上int和long的取值范围是一样的,int取值范围:-2147483648 ~ 2147483647,long取值范围:-2147483648 ~ 2147483647,故将所有数转化到[−231, 0]来进行运算,以避免负数转正数时的溢出问题。
其次不能使用乘法、除法和 mod 运算符:那就使用加法、减法、位运算等等;
最后溢出问题:主要是被除数为 Integer.MIN_VALUE 而除数为 -1 的情况,−231 / -1 = 231,因为负数的最小值的绝对值比正数的最大值大 1,所以这样算出来会溢出,这种情况需要特殊处理。
最终解题思路分为三步:
1.对边界情况进行特殊判断;
2.将被除数和除数都转换成负数,并记录最终结果的符号;
3.逐步增大除数来逼近被除数;
代码:
1 class Solution {
2 public int divide(int dividend, int divisor) {
3 //溢出情况
4 if(dividend == Integer.MIN_VALUE && divisor == -1){
5 return Integer.MAX_VALUE;
6 }
7 //记录结果的符号
8 int sign = -1;
9 //如果为两正或两负,即符号为正
10 if((dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0)){
11 sign = 1;
12 }
13 //将被除数和除数均转换成负数
14 dividend = dividend > 0 ? -dividend : dividend;
15 divisor = divisor > 0 ? -divisor : divisor;
16 //设置一个变量保存商的值
17 int quotient = 0;
18 //负数的比较与正数相反,模拟倍数的过程
19 while(dividend <= divisor){
20 //定义一个中间变量temp来保存过渡的除数的倍数
21 //定义一个count来记录倍数2^x
22 int temp = divisor,count = 1;
23 //temp + temp可能会导致整型溢出
24 //最小的int负数是 -2^31(0x80000000),它的一半是 -2³¹/2=-2³⁰(-1073741824)
25 //但因为是负数故 temp >= -1073741824
26 while(temp >=-1073741824 && (temp + temp >= dividend)){
27 temp += temp;
28 count += count;
29 }
30 //找新的被除数
31 dividend -= temp;
32 quotient += count;
33 }
34 return sign < 0 ? -quotient : quotient;
35
36 }
37 }
力扣29(java)-两数相除(中等)的更多相关文章
- Leetcode(29)-两数相除
给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 示例 1: 输 ...
- 【leetcode 29】 两数相除(中等)
题目描述 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 整数 ...
- Java实现 LeetCode 29 两数相除
29. 两数相除 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商 ...
- [LeetCode] 29. Divide Two Integers 两数相除
Given two integers dividend and divisor, divide two integers without using multiplication, division ...
- Leetcode 29.两数相除 By Python
给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 示例 1: 输 ...
- LeetCode(29): 两数相除
Medium! 题目描述: 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor ...
- LeetCode 29 - 两数相除 - [位运算]
题目链接:https://leetcode-cn.com/problems/divide-two-integers/description/ 给定两个整数,被除数 dividend 和除数 divis ...
- leetcode 29 两数相除
问题描述 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 示例 ...
- [LeetCode]29 两数相除和一个小坑点
给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 示例 1: 输 ...
- [LeetCode] Divide Two Integers 两数相除
Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...
随机推荐
- ESP8266 下安装esptool.py并使用esptool刷机神助手
一 前记 在使用ESP8266模块时,通常会用到一些刷机软件.官方提供了nodemcu_flasher.ESPFlashDownloadTool.ESP8266Flasher等下载工具,但是缺少更底层 ...
- Android Studio自带模拟器无法访问网络问题解决
测试APP的时候,发现Android Studio自带的模拟器访问不了百度等网站,之前一直用的好好的,觉得可能是版本的问题,也有可能是公司网络的问题(因为在家里的电脑的Android Studio的模 ...
- day02-自己实现Mybatis底层机制-01
自己实现Mybatis底层机制-01 主要实现:封装SqlSession到执行器+Mapper接口和Mapper.xml+MapperBean+动态代理Mapper的方法 1.Mybatis整体架构分 ...
- spring mvc 给action添加事务不成功的原因
spring springMVC ation事务管理 自己单独做了个小网站 但是发现action事务不起作用了 但是如果用service层就没问题 找了很多办法没解决 最后自己解决了 其实就是一个加载 ...
- FFmpeg命令行之ffmpeg调整音视频播放速度
FFmpeg对音频.视频播放速度的调整的原理不一样.下面简单的说一下各自的原理及实现方式: 一.调整视频速率 视频的倍速主要是通过控制filter中的setpts来实现,setpts是视频滤波器通过改 ...
- Android 开发Day5
展示项目 这是我的项目结构,补录的
- golang gc的内部优化
今天讲一个常见的gc compiler(也就是官方版本的go编译器和runtime)在垃圾回收的扫描标记阶段做的优化. 我对这个优化的描述印象最深的是在bigcache的注释里,大致内容是如果map的 ...
- KingbaseES V8R6 集群运维案例 -- 脚本部署集群后ssh无法连接
案例说明: 在kylin V10环境下,通过脚本方式部署KingbaseES V8R6集群后,发现ssh无法连接主机,通过分析发现在脚本部署过程中会对系统环境进行优化配置,在修改了/etc/ssh/s ...
- .NET分布式Orleans - 8 - 贪吃蛇项目实战(准备阶段)
到目前为止,Orleans7的核心概念基本已经学完,我准备使用Orleans7做一个项目实战,来总结自己的学习效果. 项目效果 通过Orleans7来完成一个贪吃蛇游戏,要求如下: 可以多人在线玩 贪 ...
- 区别对比 Python、Perl、VB、Ruby、C/C++、C# .Net、PHP、Java… 等多编程语言
1. 编程语言类型:首先,Python.C/C++.Java 都是强类型的编程语言.强类型的编程语言定义如下: 强类型的编程语言是一种强制类型定义的编程语言,即一旦某一个变量被定义类型,如果不经强制转 ...