题目描述:
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
就是说不使用乘法、除法和取余,来得出除法操作的结果。
分析可知,我们可以使用移位运算和加减这些,暴力方法便是不断使用减法得到结果,时间复杂度是O(n).
深知肯定还有其他的解法,可惜脑子太笨,看了别人的方法反应了很久才明白,大概思路如下:
我们知道dividend = divisor * flag_0 * 2 ^ 0 + divisor * flag_1 * 2 ^1 + …… + divisor * flag_n * 2 ^n + diff,其中flag_n为0或1,diff < divisor,当然dividend得大于divisor。到这里就好办了:
- 我们首先一个n使d = divisor * 2 ^ n = divisor * bitcnt最接近(<=)dividend,即dividend = d + leftover;
- 当dividend >= d时,使dividend = dividend - d,result = result + bitcnt,否则进入步骤3,这一步的意思就是说2 ^ n 中的flag_n是0还是1;
- d >>= 1, bitcnt >>= 1,d和bitcnt的操作很好理解,就是说2 ^ n这项考虑完了,接下来考虑2 ^ (n - 1)这项;
- 可知只要d >= divisor,我们就可以继续步骤2,直到d < divisor,即d为diff。
java代码如下:
public class Solution {
public int divide(int dividend, int divisor) {
long result = divideL(dividend, divisor);
result = result > Integer.MAX_VALUE ? Integer.MAX_VALUE : result;
return (int)result;
}
public long divideL(long dividend, long divisor){
if(divisor == 1)
return dividend;
if(divisor < 0)
return -divideL(dividend, -divisor);
if(dividend < 0)
return -divideL(-dividend, divisor);
if(divisor > dividend)
return 0;
if(divisor == 0)
return Integer.MAX_VALUE;
long copyDivisor = divisor;
int bitcnt = 1;
long result = 0;
while(copyDivisor < dividend){
copyDivisor <<= 1;
bitcnt <<= 1;
}
if(dividend < copyDivisor){
copyDivisor >>= 1;
bitcnt >>= 1;
}
while(copyDivisor >= divisor){
if(dividend >= copyDivisor){
dividend -= copyDivisor;
result += bitcnt;
}
copyDivisor >>= 1;
bitcnt >>= 1;
}
return result;
}
}
该解法的时间复杂度为O(logN);