给定两个整数,被除数 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. PAT Advanced 1005 Spell It Right (20 分)

    Given a non-negative integer N, your task is to compute the sum of all the digits of N, and output e ...

  2. Revolver Maps-3D地球仪网站定制

    这是个网站统计的小插件,大家可以看到那些国家,哪些城市对本网站进行了访问,很直观的一种表现方式. 这个小插件不需要你写任何代码,只需要去它官方网站定制你自己需要的代码.它的地址是:http://www ...

  3. 网络流 最大流SAPkuangbin模板

    hdu 1532 求1~n的最大流 #include<stdio.h> #include<string.h> #include<algorithm> #includ ...

  4. mysql merge引擎分表

    ---------------------创建表一--------------------------------------DROP TABLE a1;CREATE TABLE `a1` ( `id ...

  5. Textarea随着文本的字数自适应高度,后来发现用 contenteditable 代替textarea 效果更佳

    做移动端项目遇到很多问题,最近比如textarea 随着文本的字数自动撑开高度, 网上也查阅了一些资料发现比较有用的方法 就是获取 textarea的行数和换行符来动态改变textarea的高度  就 ...

  6. Git之仓库管理

    介绍以及安装: Git 是一个开源的分布式版本控制软件,用以有效.高速的处理从很小到非常大的项目版本管理. Git 最初是由Linus Torvalds设计开发的,用于管理Linux内核开发.Git ...

  7. [洛谷P2886] 牛继电器Cow Relays

    问题描述 For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race ...

  8. flex的12个属性

    容器(父元素)的属性: flex-direction属性决定主轴的方向 flex-wrap 属性决定项目在一行排不下的情况下是否换行 flex-flow flex-flow属性是flex-direct ...

  9. 拓展KMP以及模板

    废话不多说,上模板 #include<bits/stdc++.h> ; int Next[maxn], extend[maxn], moL, strL;///Next数组.extend数组 ...

  10. Acitiviti的查询及删除(六)

    流程定义查询 查询部署的流程定义. /** * 查询流程定义信息 //act_re_procdef */ public class QueryProcessDefinition { public st ...