题目描述
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
对两个数 dividend 和 divisor,在不使用乘法、除法、取余操作求它们的相除结果,最直观的做法就是反复对 dividend - divisor 进行计数,直到差小于divisor为止。但是该方法存在一个问题,当dividend很大而divisor很小(eg. 1)的时候,会出现Time Limit Exceed的问题。
这里,我们可以利用二进制的特点减少运行时间。
d
表示分子,
d=an∗2n+an−1∗2n−1+⋯+a1∗21+a0∗20
b=bm∗2m+bm−1∗2m−1+⋯+b1∗21+b0∗20
计算方法为:
- d=d−b -> cnt+=1;
- d=d−2∗b -> cnt+=2;
- ⋯
- d=d−2k∗b -> cnt+=2k;
- 直到 d−2k∗b<0
若此时 d<b 则计算结束,否则,重复上述计算。
上面的乘法和除法因为都是与2相关的,可以用位移操作代替。
另外需要注意可能会存在overflow的问题。这里用一个宏表示溢出时的数值即可。
#define MAX_INT 2147483647 /* maximum (signed) int value */
class Solution {
public:
int divide(int dividend, int divisor) {
long long a = dividend;
long long b = divisor;
a = abs(a); b = abs(b);
long long int res = 0;
while (a>=b)
{
long long t = b;
for (int i = 1; a >= t; i <<= 1, t <<= 1)
{
a -= t;
res += i;
}
}
res = ((dividend<0)^(divisor<0))? -res:res;
if (res > MAX_INT)
res = MAX_INT;
return res;
}
};