【剑指 Offer II 001. 整数除法】同leedcode 29.两数相除
剑指 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.两数相除的更多相关文章
- 刷题-力扣-剑指 Offer II 055. 二叉搜索树迭代器
剑指 Offer II 055. 二叉搜索树迭代器 题目链接 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/kTOapQ 著作权归领扣网络所有 ...
- 剑指Offer - 九度1504 - 把数组排成最小的数
剑指Offer - 九度1504 - 把数组排成最小的数2014-02-06 00:19 题目描述: 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输 ...
- 剑指Offer - 九度1352 - 和为S的两个数字
剑指Offer - 九度1352 - 和为S的两个数字2014-02-05 18:15 题目描述: 输入一个递增排序的数组和一个数字S,在数组中查找两个数,是的他们的和正好是S,如果有多对数字的和等于 ...
- 【剑指Offer】孩子们的游戏(圆圈中最后剩下的数) 解题报告(Python)
[剑指Offer]孩子们的游戏(圆圈中最后剩下的数) 解题报告(Python) 标签(空格分隔): 剑指Offer 题目地址:https://www.nowcoder.com/ta/coding-in ...
- 【剑指Offer面试编程题】题目1505:两个链表的第一个公共结点--九度OJ
题目描述: 输入两个链表,找出它们的第一个公共结点. 输入: 输入可能包含多个测试样例. 对于每个测试案例,输入的第一行为两个整数m和n(1<=m,n<=1000):代表将要输入的两个链表 ...
- 【剑指Offer面试编程题】题目1214:丑数--九度OJ
把只包含因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. 输入: 输入包括一个 ...
- 剑指Offer 数值的整数次方
题目描述 给定一个double类型的浮点数base和int类型的整数exponent.求base的exponent次方. 思路: 要考虑边界,0,负数 AC代码: class Solution ...
- 剑指offer之关于整数的处理
首先是整数次方的处理 在这处理的时候有几个细节主义处理 1.当指数是负数的时候 2.当指数式0的时候 3.当不满足条件的时候要抛出异常 再一个就是常用的将一个树化为二进制的形式,或者是求整数的幂或者矩 ...
- 《剑指offer》-统计整数二进制表示中1的个数
题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 直观思路就是把二进制表示从右往左统计1的个数.直接想到移位操作来迭代处理.坑点在于负数的移位操作会填充1.有人贴出了逻辑移位 ...
随机推荐
- Solon Web 开发,二、开发知识准备
Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...
- 【刷题-PAT】A1108 Finding Average (20 分)
1108 Finding Average (20 分) The basic task is simple: given N real numbers, you are supposed to calc ...
- 【经验总结-markdown】markdown字体和颜色设置
字体设置 关键词为face <font face = "黑体">我是黑体</font> <font face = "宋体"> ...
- elasticsearch之请求处理流程(Rest/RPC )
.Action概述 ES提供client供集群节点或java客户端访问集群用.client模块通过代理模式,将所有的操作都集成到client接口中.这样外部调用只需要初始化client就能够完成所有的 ...
- gin框架中的中间件
全局中间件 所有请求都经过此中间件 中间件中设置值 func MiddleWare() gin.HandlerFunc { return func(context *gin.Context) { t ...
- golang中time包日期时间常用用法
package main import ( "fmt" "reflect" "time" ) var week time.Duration ...
- Android Native -- Message/Handler/Looper机制(原理篇)
⌈Android Native消息队列处理系列文章⌋ Android Native -- Message/Handler/Looper机制(原理篇) Android Native -- Message ...
- ant -design vue a-tree 树形控件
话不多说,先上代码. <a-tree v-if="this.treeData && this.treeData.length > 0" ref=&quo ...
- 带你十天轻松搞定 Go 微服务系列(六)
序言 我们通过一个系列文章跟大家详细展示一个 go-zero 微服务示例,整个系列分十篇文章,目录结构如下: 环境搭建 服务拆分 用户服务 产品服务 订单服务 支付服务(本文) RPC 服务 Auth ...
- NOIP PJ/CSP-J 题目选做
1. luoguP7074 [CSP-J2020] 方格取数 2. luoguP5662 [CSP-J2019] 纪念品 3. luoguP2671 [NOIP2015 普及组] 求和 4. luog ...