剑指 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. html,js 获取父窗口元素

    $("#父窗口元素ID",window.parent.document) window.parent.document.getElementById("父窗口元素ID&q ...

  2. Ajax_GET的一个基本用法

    Ajax_GET的一个基本用法 首先先创建一个Server.js文件 ​//1.引入express// const { response } = require('express');const ex ...

  3. WPF学习笔记(四):AvalonEdit 代码高亮编辑控件专题

    AvalonEdit 是一个基于 WPF 的文本编辑器组件.它是由 Daniel Grunwald 为 SharpDevelop 编写的.从 5.0 版开始,AvalonEdit 根据MIT许可证发布 ...

  4. 20个 CSS 快速提升技巧

    作者:web秀 http://www.javanx.cn/20190321/css-skill/ 本文涵盖了20个css技巧,可以解决许多工作中常见的问题. 1.使用CSS重置(reset) css重 ...

  5. Jupyter Notebook 更改字体、字体大小、行高

    (废话):今天在做实验的时候遇到了一点问题,就问了问本科的室友,结果室友推荐我使用Jupyter Notebook来写代码,以前看其他同学使用过,但是一直在用Pycharm写,需要的时候顶多是Debu ...

  6. Vue2和Vue3技术整理3 - 高级篇

    3.高级篇 前言 基础篇链接:https://www.cnblogs.com/xiegongzi/p/15782921.html 组件化开发篇链接:https://www.cnblogs.com/xi ...

  7. 300iq Contest 1 C Cool Pairs

    为了构造时恰好取到 \(k\) 对时的方便,可以考虑将 \(a\) 设为互不相同的 \(n\) 个数,这样对每个 \(b\) 的取值对答案的贡献就是可以通过调整变成任意值的. 因为要尽可能造成贡献,因 ...

  8. JS 基本类型的包装对象

    笔记整理自:廖雪峰老师的JS教程 目录 包装对象 不写new的作用 总结 注意 包装对象 JavaScript还提供了包装对象,熟悉Java的小伙伴肯定很清楚int和Integer这种暧昧关系. nu ...

  9. 版本控制SVN

    为什么需要版本控制软件 代码的冻结 避免在重大的考核之前改动代码 每个稳定版本都在服务器保存进度,随时可以回退 需求频繁的变化不要改动稳定的代码,不要改别人写好的代码 为什么需求会变化?有时候产品自己 ...

  10. action标签中method={1}怎么理解

    其实用到method={数字}的时候,相应的前面的action是要出现*通配符来搭配的.比如一个小例子:<action name="user_*" class="U ...