剑指 Offer II 001. 整数除法



解题思路

  • 在计算的时候将负数转化为正数,对于32位整数而言,最小的正数是-2^31, 将其转化为正数是2^31,导致溢出。因此将正数转化为负数不会导致溢出。
  • 设置一个变量,用来记录正数个数,以便在最后的结果调整正负号。
  • 特殊情况,可能溢出的情况讨论,由于是整数除法,除数不为0,商的值一定小于等于被除数的绝对值,因此,int型溢出只有一种情况,(-2^31)/(-1) = 2^31。

最容易想到的是通过减法代替除法,但是会超时

class Solution {
public int divide(int a, int b) {
if(a == 0)return 0;
int symbolNum = (a>0)^(b>0)? -1:1 ;//可以对下面的代码段进行优化
/*
int symbolNum = 1;
if(a>0&&b>0 || a<0&&b<0) symbolNum = 1;
else{
symbolNum = -1;
}*/ if(a==Integer.MIN_VALUE && b==-1) return Integer.MAX_VALUE; if(a>0)a = -a;
if(b>0)b = -b;
int ans = 0;
while(a <= b){
a -= b;
ans++;
}
return symbolNum == -1? -ans:ans;
}
}

优化思路

不使用减法那种被除数对除数一次一次减的形式(在被除数过大而除数很小的情况下会超时),而是试图减2个、4个、8个....找到最大的2的n次方。将被除数减去除数的2的n次方倍,然后将剩余的被除数重复前面的步骤。

例如:

为了求得15/2的商,先从15里减去8 (23),得到7;再从7里减去4(22),得到3;再从3里减去2(2^1),得到1,此时1小于2,因此商是3+2+1=7。

在计算两个负数的除法时,防止每次计算除数的2倍,会导致大数溢出,要保证计算2倍之后的数大于(-231)/2。如果时计算两个正数的除法,要保证计算2倍之后的数小于(231-1)/2。

class Solution {
public int divide(int a, int b) {
//int 型整数的除法只有一种情况会导致溢出,即(-2^31)/(-1)
if(a==Integer.MIN_VALUE && b==-1) return Integer.MAX_VALUE;
if(a == 0 || b == 1)return a;
else if(b == -1) return -a;
int symbolNum = (a>0)^(b>0)? -1:1 ;
// 由于(-2^31) 转换为正数会溢出,但是任意正数转换为负数都不会溢出
// 故,记录负数的个数,并将正数转换为负数方便统一计算
if(a>0)a = -a;
if(b>0)b = -b; // while(a <= b){//这样写确实可以过案例,但是会超时
// a -= b;
// ans++;
// }
if(a == b)return symbolNum == -1? -1:1;
int ans = 0;
while(a<=b){//小于是因为现在a,b都是负数
int value = b;//统计最多有几个减数(2的n次方个)
int tmpQuotient = 1;
while(value + value > Integer.MIN_VALUE && value + value >= a){//减到不够了为止
value += value;
tmpQuotient += tmpQuotient;
}
ans +=tmpQuotient;
a -= value;
} return symbolNum == -1? -ans:ans;
} }

但上述代码只通过了700+样例,找了半天发现是value + value > Integer.MIN_VALUE这里出问题了,要改成value >0xc0000000。(0xc0000000是Integer.MIN_VALUE的一半)

完整代码贴在这儿

class Solution {
public int divide(int a, int b) {
//int 型整数的除法只有一种情况会导致溢出,即(-2^31)/(-1)
if(a==Integer.MIN_VALUE && b==-1) return Integer.MAX_VALUE;
if(a == 0 || b == 1)return a;
else if(b == -1) return -a;
int symbolNum = (a>0)^(b>0)? -1:1 ;
// 由于(-2^31) 转换为正数会溢出,但是任意正数转换为负数都不会溢出
// 故,记录负数的个数,并将正数转换为负数方便统一计算
if(a>0)a = -a;
if(b>0)b = -b; // while(a <= b){//这样写确实可以过案例,但是会超时
// a -= b;
// ans++;
// }
if(a == b)return symbolNum == -1? -1:1;
int ans = 0;
while(a<=b){//小于是因为现在a,b都是负数
int value = b;//统计最多有几个减数(2的n次方个)
int tmpQuotient = 1;
while(value >0xc0000000 && value + value >= a){//减到不够了为止
value += value;
tmpQuotient += tmpQuotient;
}
ans +=tmpQuotient;
a -= value;
} return symbolNum == -1? -ans:ans;
} }

这里补充一下int 类型数据的最大值,最小值及其十六进制表示方式:

在int类型(32位)中:

正整数的最大值为 0x7fffffff 也就是十进制的 2147483647

正整数的最小值为 0x00000001 也就是十进制的 1

0表示为:0x00000000

负整数的最大值为 0xffffffff 也就是十进制的 -1

负整数的最小值为 0x80000000 也就是十进制的 -2147483648

【剑指 Offer II 001. 整数除法】同leedcode 29.两数相除的更多相关文章

  1. 刷题-力扣-剑指 Offer II 055. 二叉搜索树迭代器

    剑指 Offer II 055. 二叉搜索树迭代器 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/kTOapQ 著作权归领扣网络所有 ...

  2. 剑指Offer - 九度1504 - 把数组排成最小的数

    剑指Offer - 九度1504 - 把数组排成最小的数2014-02-06 00:19 题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输 ...

  3. 剑指Offer - 九度1352 - 和为S的两个数字

    剑指Offer - 九度1352 - 和为S的两个数字2014-02-05 18:15 题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于 ...

  4. 【剑指Offer】孩子们的游戏(圆圈中最后剩下的数) 解题报告(Python)

    [剑指Offer]孩子们的游戏(圆圈中最后剩下的数) 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-in ...

  5. 【剑指Offer面试编程题】题目1505:两个链表的第一个公共结点--九度OJ

    题目描述: 输入两个链表,找出它们的第一个公共结点. 输入: 输入可能包含多个测试样例. 对于每个测试案例,输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的两个链表 ...

  6. 【剑指Offer面试编程题】题目1214:丑数--九度OJ

    把只包含因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 输入: 输入包括一个 ...

  7. 剑指Offer 数值的整数次方

    题目描述 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方.   思路: 要考虑边界,0,负数   AC代码: class Solution ...

  8. 剑指offer之关于整数的处理

    首先是整数次方的处理 在这处理的时候有几个细节主义处理 1.当指数是负数的时候 2.当指数式0的时候 3.当不满足条件的时候要抛出异常 再一个就是常用的将一个树化为二进制的形式,或者是求整数的幂或者矩 ...

  9. 《剑指offer》-统计整数二进制表示中1的个数

    题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 直观思路就是把二进制表示从右往左统计1的个数.直接想到移位操作来迭代处理.坑点在于负数的移位操作会填充1.有人贴出了逻辑移位 ...

随机推荐

  1. 【Android】安卓四大组件之Activity(二)

    [Android]安卓四大组件之Activity(二) 前言 在这篇文章之前,我已经写过了一篇有关Activity的内容,是关于activity之间的页面跳转和数据传递,而这篇文章着重强调的是Acti ...

  2. 毫米转像素dpi

    public static double MillimeterToPixel_X(double length) //length是毫米,1厘米=10毫米 { System.Windows.Forms. ...

  3. IDEA2017 maven Spark HelloWorld项目(本地断点调试)

    作为windows下的spark开发环境 1.应用安装 首先安装好idea2017 java8 scalaJDK spark hadoop(注意scala和spark的版本要匹配) 2.打开idea, ...

  4. Linux无写权限打zip

    opt下tiger.txt没权限得时候可以这样直接用zip打包 zip /tmp/1.zip /opt/tiger.txt

  5. springboot 配置百里香 thymeleaf?

    一.1.1父级工程导入jar包. springboot已经完整把thymeleaf集成进框架中了,可以直接添加使用不需要任何的配置信息 <dependency> <groupId&g ...

  6. css自定义属性(css变量)

    感谢原文作者:Kuku殿下 原文链接:https://segmentfault.com/a/1190000015948538 前言 刚开始的"css变量",经扩展之后,称为&quo ...

  7. 【转载】Locust实现集合点

    直接编写接口事务脚本对后台接口进行测试:有时测试需要让所有并发用户完成初始化后再进行压力测试,这就需要类似于LoadRunner中的集合点的概念,由于框架本身没有直接封装,有如下办法实现: from ...

  8. NSArray 遍历

    1.NSArray的下标遍历 NSArray *arr = @[p1, p2, p3, p4, p5]; for (int i = 0; i < arr.count; ++i) { Person ...

  9. sql作业题

    作业题:1.查询选修课程'3-105'且成绩在60到80之间的所有记录.注释:用于指定某个范围使用between and,也可以使用and连接符;答案:法1:select * from sc wher ...

  10. MySQL事务以及存储引擎

    MySQL事务以及存储引擎 目录 MySQL事务以及存储引擎 一.事务 1. 事务的概念 2. 事务的ACID特点 (1)原子性 (2)一致性 (3)隔离性 ①事务之间的相互影响 ②MySQL事务支持 ...