力扣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 ...
随机推荐
- debian卡顿,造成用户注销现象的原因以及解决方法
现象:当时电脑正在运行,宝塔面板安装初始化应用,一个浏览器,一个虚拟机 解决方法:目前还不清楚--是不是负载过大?好奇怪!
- IDEA/Android Studio的gradle控制台输出中文乱码问题解决
原文地址: IDEA/Android Studio的gradle控制台输出中文乱码问题解决 - Stars-One的杂货小窝 在项目中,有使用到Gradle自定义脚本,会有些输出日志,但是输出中文就变 ...
- C++红黑树的实现
最近闲来无事,一直没有研究过红黑树,B树,B+树之类的,打算自己用C语言实现一下它们. 红黑树的性质定义: 节点只能是黑色或者红色. 根节点必须是黑色. 每个叶子节点是黑色节点(称之为NIL节点,又被 ...
- 谈谈Redis五种数据结构及真实应用场景
前言 如果问你redis有哪些数据结构,你肯定可以一口气说出五种基本数据结构: String(字符串).Hash(哈希).List(列表).Set(集合).zset(有序集合) 你或许还知道它还有三种 ...
- Java Spring Redis 如何向Set中添加List?
调用list.toArray方法将list转成数组,再使用add方法参数传入数组,即可批量添加. redisTemplate.opsForSet().add(key,collect.toArray(n ...
- java基础 韩顺平老师的 面向对象(中级) 自己记的部分笔记
272,包基本介绍 包的三大作用 1,区分相同的类 2,当类很多时,可以很好的管理类 3,控制访问范围 包基本用法 package com.hspedu; 说明: 1,package 关键字, ...
- 记录--Vue开发历程---音乐播放器
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.audio标签的使用 1.Audio 对象属性 2.对象方法 二.效果 效果如下: 三.代码 代码如下: MusicPlayer.vu ...
- css实现按钮点击水波纹效果和两边扩散效果
废话少说,先上代码了,复制到html中即可使用 点击查看代码 <!DOCTYPE html> <html lang="en"> <head> & ...
- 关于GDPR体系文件介绍,介绍GDPR体系文件的内容和意义
随着数字化时代的到来,个人数据保护成为了一个日益受到关注的问题.欧盟于2018年5月25日颁布了"通用数据保护条例"(GDPR),旨在加强对欧洲公民个人数据的保护.GDPR对企业和 ...
- springBoot打war包部署tomcat
1.修改maven的pom.xml文件 <packaging>war</packaging> 2.排除springboot内嵌的tomcat <dependency> ...