给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

返回被除数 dividend 除以除数 divisor 得到的商。

示例 1:

输入: dividend = 10, divisor = 3
输出: 3
示例 2: 输入: dividend = 7, divisor = -3
输出: -2
说明: 被除数和除数均为 32 位有符号整数。
除数不为 0。
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。

  

思路一:

就是小学时候还没学除法的时候用的办法,用被减数去重复减去减数,但是毫无疑问这种办法效率并不高。如果其中一个Integer.MAX_VALUE

另一个是1,就得循环那么多次,显然这不是做这个的好的解决办法。

思路二:

那么除了一个个将还有什么效率好的办法呢,我开始也想用移位,但是还是没能想出来,毕竟太菜。

因为dividend即被减数规定了范围,那么能够被减数能整除的最大整数就是2的31次方,那么,从2的31依次开始试探,试探数之间的关系就是二倍关系。二倍关系就跟移位操作挂上够了,左移相当于X2,右移相当于/2,如果被除数/2^i(i=31,30...1,0)的商是大于除数的,则本题答案可以加上此时的2^i,同时,将被减数减去2^i,当然,在此之前,为了避免两个数异号而带来的不便,事先将两个数字做一下绝对值处理就好了。

然后根据这条思路写出了如下代码:

class Solution {
public int divide(int dividend, int divisor) {
boolean is = false;
int res = 0;
if(dividend==0)
return 0;
if(divisor==1)
return dividend;
if(dividend==Integer.MIN_VALUE&&divisor==-1)
return Integer.MAX_VALUE;
if((dividend<0&&divisor>0)||(dividend>0&&divisor<0))
is = true;//如果异号
long divd = Math.abs(dividend);
long divs = Math.abs(divisor);
for(int i = 31;i>=0;i--){
if((divd>>i)>=divs){
res+=1<<i;
divd-=divs<<i;
}
}
return is?-res:res;//异号结果变负
}
}

测几个用例,诶好像没问题。提交,WA(哭)

输入:
-2147483648
2
输出:
0
预期:
-1073741824

  

一时半会没想通,直到看见Math.abs()的源代码:

  /**
* Returns the absolute value of an {@code int} value.
* If the argument is not negative, the argument is returned.
* If the argument is negative, the negation of the argument is returned.
*
* <p>Note that if the argument is equal to the value of
* {@link Integer#MIN_VALUE}, the most negative representable
* {@code int} value, the result is that same value, which is
* negative.
*
* @param a the argument whose absolute value is to be determined
* @return the absolute value of the argument.
*/
public static int abs(int a) {
return (a < 0) ? -a : a;
}

  

如果是Integer.MIN_VALUE,不返回绝对值,返回本身。。所以这里算是一个小坑点了,做法就是,将int转化为long来去绝对值(因为本题规定了被除数范围,如果没有规定,强制转为long也可能没用。。)

最后的AC代码:

class Solution {
public int divide(int dividend, int divisor) {
boolean is = false;
int res = 0;
if(dividend==0)
return 0;
if(divisor==1)
return dividend;
if(dividend==Integer.MIN_VALUE&&divisor==-1)
return Integer.MAX_VALUE;
if((dividend<0&&divisor>0)||(dividend>0&&divisor<0))
is = true;//如果异号
long divd = Math.abs((long)(dividend));
long divs = Math.abs((long)(divisor));
for(int i = 31;i>=0;i--){
if((divd>>i)>=divs){
res+=1<<i;
divd-=divs<<i;
}
}
return is?-res:res;//异号结果变负
}
}

[LeetCode]29 两数相除和一个小坑点的更多相关文章

  1. Java实现 LeetCode 29 两数相除

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

  2. Leetcode 29.两数相除 By Python

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

  3. leetcode 29 两数相除

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

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

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

  5. LeetCode 29——两数相除

    1. 题目 2. 解答 2.1. 方法一 题目要求不能使用乘法.除法和除余运算,但我们可以将除法转移到对数域. \[ \frac{a}{b} = e^{\frac{lna}{lnb}} = e^{ln ...

  6. leetcode 29两数相除

    我理解本题是考察基于加减实现除法,代码如下: class Solution { public: //只用加减号实现除法, //不用加减号实现除法: int divide(int dividend, i ...

  7. 【剑指 Offer II 001. 整数除法】同leedcode 29.两数相除

    剑指 Offer II 001. 整数除法 解题思路 在计算的时候将负数转化为正数,对于32位整数而言,最小的正数是-2^31, 将其转化为正数是2^31,导致溢出.因此将正数转化为负数不会导致溢出. ...

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

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

  9. Leetcode(29)-两数相除

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

随机推荐

  1. laplace transform 拉普拉斯变换

    参考网址: 1. https://en.wikipedia.org/wiki/First-hitting-time_model 2. https://en.wikipedia.org/wiki/Lap ...

  2. Zookeeper学习笔记(上)

    Zookeeper学习笔记 本篇主要是一些基本的介绍和API的使用介绍, 有些只是记录了知识点,而没有完全在笔记中详细解释, 需要自行查找资料补充相关概念 主要参考了课程中的内容: Zookeeper ...

  3. Python---TKinter项目实战---屏保

    ### 项目分析 - 屏保可以自己启动,也可以手动启动 - 一旦敲击键盘或者移动鼠标后,或者其他的引发时间,则停止 - 如果屏保是一幅画的话,则没有画框 - 图像的动作是随机的,具有随机性,可能包括颜 ...

  4. python multiprocessing pool

    python 本身是不是单线程这个我真心搞不懂 但是我是来吐槽的: multiprocessing.Pool(precesses = 2) 这个语句曾经让我的内存爆满,死机不解释. 在重装 pytho ...

  5. JSP文件的上传和下载

    文件上传下载,与传统的方式不同,这里能够上传和下载10G以上的文件.而且支持断点续传. 通常情况下,我们在网站上面下载的时候都是单个文件下载,但是在实际的业务场景中,我们经常会遇到客户需要批量下载的场 ...

  6. 基于点云的3ds Max快速精细三维建模方法及系统的制作方法 插件开发

                                 基于点云的3ds Max快速精细三维建模方法及系统的制作方法[技术领域][0001]本发明涉及数字城市三维建模领域,尤其涉及一种基于点云的3d ...

  7. git 部署服务

    git 知识 服务器知识 1.在本地完成代码的编写, 然后通过 git 管理版本. 在编码完成后 git push 到 git 云端(github 或者 码云 及其他). 2.在服务器端安装 git ...

  8. 在XenCenter6.2中构建CentOS7虚拟机的启动错误

    在XenCenter6.2中创建CentOS7虚拟机时,发现系统并没有提供CentOS7 64bit的模板,只有CentOS6 64bit模板.如果采用CentOS6作为其模板来创建CentOS7虚拟 ...

  9. 官方文档翻译-Today

    原文链接: Today 最后更新:2017-02-18 译文: 应用的今日视图扩展被称作小部件.小部件为用户提供快速访问重要信息的入口.例如,用户打开今日视图实时查看股票价格或天气情况,查看今天的日程 ...

  10. httpscan 爬虫式的网段Web主机发现小工具

    httpscan是一个扫描指定网段的Web主机的小工具.和端口扫描器不一样,httpscan是以爬虫的方式进行Web主机发现,因此相对来说不容易被防火墙拦截.httpscan会返回IP http状态码 ...