题目
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
示例 1:
输入: dividend = 10, divisor = 3
输出: 3
示例 2:
输入: dividend = 7, divisor = -3
输出: -2
思路:
思路1:通过循环用除数不断去减被除数,当被除数小于除数时,相减的次数即为商。但当被除数相当大,除数相当小时(dividend=2^31,divisor = 1)势必会消耗很多时间,最终导致超时。
思路2:位运算的效率很高,左移1位乘2,右移以为除以2,我们先可以把一个被除数除以2^n,即向右移动n位,由于该数为带符号数,起初n为31,然后不断减小n逐渐逼近除数,当dividend/2^n>=divisor,如果被除数-除数*2^n小于除数时,则2^n即为商,如果被除数-除数*2^n大于除数时,再次用上述方法循环一次。
java:
class Solution {
public static void main(String[] args) {
System.out.println(divide(10,3));
System.out.println(1<<3);
}
public static int divide(int dividend, int divisor) {
boolean Symbol = (dividend ^ divisor) >= 0; //如果大于0 两数符号相同
long _dividend = (Math.abs((long)dividend));
long _divisor = (Math.abs((long)divisor));
if(dividend == Integer.MIN_VALUE && divisor == -1){
return Integer.MAX_VALUE;
} //int最小值为2^31,除以-1就是2^31,但int最大取值2^31-1,会导致溢出
int result = 0;
for(int i = 31;i>=0;i--){
if((_dividend>>i)>=_divisor){
result = result + (1<<i);
_dividend = _dividend - (_divisor<<i);
}
}
if(Symbol == true){
return result;
}
else
return -result;
}
}
坑:
1.long _dividend = ((long)Math.abs(dividend)); 起初将long写在了Math外面导致在求绝对值时就已经溢出了,应该改为long _dividend = (Math.abs((long)dividend));