题目:

给定两个整数,被除数 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 = 12;

2.计算3的2x的最大值(不超过11),对3不断的翻倍,3-->6-->12,此时的11超过6,即用11-6 = 5,5作为新的被除数,3 * 2 = 6;

3.计算3的2x的最大值(不超过5),对3不断的翻倍,3-->6,此时的6超过5,即用6-5 = 1,1作为新的被除数,3 * 2 = 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 = 80;

2.计算5的2x的最大值(不超过17),对5不断的翻倍,5-->10-->20,此时的20超过17,即用17-10 = 7,7作为新的被除数,5 * 2 = 10;

3.计算5的2x的最大值(不超过7),对5不断的翻倍,5-->10,此时的10超过7,即用7-5 = 2,2作为新的被除数,5 * 2 = 5;

4.新的被除数2已经小于5了,计算结束,商为2+ 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)-两数相除(中等)的更多相关文章

  1. Leetcode(29)-两数相除

    给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 示例 1: 输 ...

  2. 【leetcode 29】 两数相除(中等)

    题目描述 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 整数 ...

  3. Java实现 LeetCode 29 两数相除

    29. 两数相除 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商 ...

  4. [LeetCode] 29. Divide Two Integers 两数相除

    Given two integers dividend and divisor, divide two integers without using multiplication, division ...

  5. Leetcode 29.两数相除 By Python

    给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 示例 1: 输 ...

  6. LeetCode(29): 两数相除

    Medium! 题目描述: 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor ...

  7. LeetCode 29 - 两数相除 - [位运算]

    题目链接:https://leetcode-cn.com/problems/divide-two-integers/description/ 给定两个整数,被除数 dividend 和除数 divis ...

  8. leetcode 29 两数相除

    问题描述 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 示例 ...

  9. [LeetCode]29 两数相除和一个小坑点

    给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 示例 1: 输 ...

  10. [LeetCode] Divide Two Integers 两数相除

    Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...

随机推荐

  1. react build 后,打包后自动将index.html copy 404.html - create-react-app 创建的项目

    起因:build上传gitee,启用路由需要404.html自动跳转 当前环境 create-react-app 搭建的架子 解决方案 由于默认的时候把build.js打包,无法查看,只好eject ...

  2. linux环境下基于python的OpenCV 保存视频

    一 概念 在OpenCV中保存视频使用的是VedioWriter对象,在其中指定输出文件的名称, A 创建视频写入的对象 out = cv2.VideoWriter(filename,fourcc, ...

  3. IDEA/Android Studio的gradle控制台输出中文乱码问题解决

    原文地址: IDEA/Android Studio的gradle控制台输出中文乱码问题解决 - Stars-One的杂货小窝 在项目中,有使用到Gradle自定义脚本,会有些输出日志,但是输出中文就变 ...

  4. springboot使用pagehelper

    自己写的用户系统项目需要加个分页,之前都是用现成的,或者使用在sql里面拼接分页查询,这次任务紧急想直接找个包实现吧,找了很多博客看了都不行啊,不知道为啥,最后还是找了之前maven使用的包才行,简单 ...

  5. python面向对象(多态)

    # 1.什么是多态:同一事物有多种形态 class Animal: # 同一类事物:动物 def talk(self): pass class Cat(Animal): # 动物的形态之一:猫 def ...

  6. tomcat中虚拟主机以及web应用程序的配置

    一:新建虚拟主机 1. 在tomcat里新建文件夹myapps,在里面添加ROOT文件,放入网站的首页文件 新建文本文档,输入你想要的内容我这里的内容是TOM.AI,把文本文档的名字改成index.h ...

  7. RageFrame学习笔记:创建路由+导入layui

    这是我写的学习RageFrame的第二篇,这一篇给大家分享下我是如何创建路由,导入外部js,css文件的,这里写下我的全部流程,希望对大家有所帮助. 话不多说,直接开始,在上一章中,我们已经把项目实例 ...

  8. 记一次 .NET某游戏后端API服务 CPU爆高分析

    一:背景 1. 讲故事 前几天有位朋友找到我,说他们的API服务程序跑着跑着CPU满了降不下去,让我帮忙看下怎么回事,现在貌似民间只有我一个人专注dump分析,还是申明一下我dump分析是免费的,如果 ...

  9. SpringBoot如何优雅的进行参数校验

    写在前面 上一篇文章中我们学会了如何优雅的接收前端参数,传送门 SpringBoot如何优雅的接收前端参数 接收到参数后,接下来要做的就是校验参数的合法性.这一步的重要性就不用多说了. 即使前端已经对 ...

  10. KingbaseES 配置 Hugepage

    前言 大页的作用是为了提升内存管理的效率,减少内存管理资源消耗(节省pagetable的开销),特别是对于大内存的情况,同时,由于hugepage相对与4k的页面,它更不容易被交换出内存,因此,它的作 ...