要正确地解答这道题目,需要注意三点。第一点,题目要求不能够使用乘法、除法和取模运算,所以我们只能够使用加减法和位移运算。第二点,任何一个整数num,都能表示为如下形式:num=c+a0*d*2^0+a1*d*2^1+a2*d*2^2+...+an*d*2^n,其中c在这里>=0并且<d,ai为0或者1,d为>=1的整数。第三点,要注意一些边界情况,比如dividend为INT_MIN并且divisor为-1。算法思想是,我们找出pDivisor能够左移的最大次数numShift,使得pDivisor<<numShift刚刚大于pDividend,这时numShift类似于第二点中的n+1,然后我们记录下pDivisor在这部分获取到的倍数1<<(numShift-1),并将pDividend减去pDivisor<<(numShift-1),并开始下一循环。详细代码如下:
class Solution {
public:
int divide(int dividend, int divisor) {
// 处理特殊情况
if (divisor==0) {
return INT_MAX;
}
if (divisor==-1 && dividend==INT_MIN) {
return INT_MAX;
}
// 得到非负数
long long pDividend = abs((long long)dividend); // 一定要强制类型转化,否则abs(INT_MIN)的结果会非常奇怪
long long pDivisor = abs((long long)divisor);
int result = 0;
while (pDividend>=pDivisor) { // 要写等号
// 计算左移多少次可以使pDivisor<<numShift刚刚大于pDividend
int numShift = 0;
while (pDividend>=(pDivisor<<numShift)) {
numShift++;
}
result += 1<<(numShift-1);
pDividend -= pDivisor<<(numShift-1);
}
if ((divisor>0 && dividend>0) || (divisor<0 && dividend<0)) {
return result;
} else {
return -result;
}
}
};