Given two integers dividend and divisor, divide two integers without using multiplication, division, and mod operator.
The integer division should truncate toward zero, which means losing its fractional part. For example, 8.345 would be truncated to 8, and -2.7335 would be truncated to -2.
Return the quotient after dividing dividend by divisor.
Note: Assume we are dealing with an environment that could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. For this problem, if the quotient is strictly greater than 231 - 1, then return 231 - 1, and if the quotient is strictly less than -231, then return -231.
Example 1:
Input: dividend = 10, divisor = 3
Output: 3
Explanation: 10/3 = 3.33333… which is truncated to 3.
计算两个整数的除法,但是不能用乘法,除法和mod操作。
结果靠近0取整。
思路:
最简单的想法就是不断用被除数 - 除数,看能减多少次。但是这样的计算量有时会很大,比如被除数很大,除数很小的时候。
于是可通过把除数不断x2,直到接近被除数,这样计算量就是logN级别的。
而且注意到整数的范围是[−231, 231 − 1],负边界比正边界的绝对值大,
这就导致了如果被除数是负边界,而除数是-1,结果就会溢出。这种情况直接返回INT_MAX。
为了方便,会首先判断结果的符号,然后用被除数和除数的绝对值来计算,
这样还是刚才的问题,负边界的绝对值又溢出了,所以要转为long型来计算。
public int divide(int dividend, int divisor) {
if(dividend == Integer.MIN_VALUE && divisor == -1)
return Integer.MAX_VALUE;
int res = 0;
int sign = (dividend > 0) ^ (divisor > 0) ? -1 : 1;
long dvd = Math.abs((long)dividend);
long div = Math.abs((long)divisor);
while(dvd >= div) {
long tmp = div;
long mul = 1;
//注意这里是while,不是if,if会TLE
while(dvd >= (tmp << 1)) {
tmp <<= 1;
mul <<= 1;
}
dvd -= tmp;
res += mul;
}
return sign==1 ? res : -res;
}