【剑指 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.有人贴出了逻辑移位 ...
随机推荐
- JavaScript输出的两种方式
var a="Hello World" document.write(a) //在网页上输出:Hello World var a="Hello World" c ...
- Java打印空心菱形
使用Java打印空心菱形 public static void main(String[] args) { int n = 5; //这里输出菱形的上半部分 for (int i = 1; i < ...
- Docker 私服
目录 什么是 Docker 私服? Docker 私服搭建 上传镜像至私服 从私服拉取镜像 什么是 Docker 私服? Docker 官方的 Docker Hub 是一个用于管理公共镜像的仓库,我们 ...
- 记录python2.7迁移到python3.6过程中的一些代码差异
python2.7 python 3.6 import urllib2 import urllib import urlparse import urllib import exceptions 废弃 ...
- Natasha 4.0 探索之路系列(四) 模板 API
Natasha 模板 Natasha 在编译单元的基础上进行了封装整理, 并提供了多种模板帮助开发者构建功能. 使用此篇的 API 前提是您对 C# 非常熟悉, 对系统的一些类型足够了解. 据此 Na ...
- vscode自定义代码片段,自定义注释片段(动态时间)
下载vscode 一.打开vscode,点击左下角设置图标. 二.点击用户代码片段 三.点击新建全局代码片段文件 四.输入自定义代码片段配置文件名,例如:vue.json 五.进行代码片段配置示例如下 ...
- 《Spring Boot 实战纪实》之过滤器
导航 什么是过滤器 Spring的过滤器 Filter定义 过滤的对象 典型应用 过滤器的使用 Filter生命周期 过滤器链 自定义敏感词过滤器 新增自定义过滤器 添加 @WebFilter注解 添 ...
- [免费下载应用]iNeuKernel.Ocr 图像数据识别与采集原理和产品化应用
目 录 1..... 应用概述... 2 2..... 免费下载试用... 2 3..... 视频介绍... 2 4..... iNeuLink.Ocr图像数据采集应用... 2 5... ...
- (DDS)正弦波形发生器——幅值、频率、相位可调(一)
(DDS)正弦波形发生器--幅值.频率.相位可调 一.项目任务: 设计一个幅值.频率.相位均可调的正弦波发生器. 频率每次增加1kHz. 相位每次增加 2*PI/256 幅值每次增加两倍 二.文章内容 ...
- 解决github.com无法访问
解决 绕过DNS解析,直接使用本地DNS记录进行直接跳转. DNS查询 在浏览器中打开DNS查询网站:http://tool.chinaz.com/dns?type=1&host=github ...