@author stormma
@date 2017/10/27 10:02
生命不息,奋斗不止!
题目
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
思路分析
方案1
被除数-除数,ans++,但是这样如果被除数和除数数值差距比较大,会TLE,所以我们得用不同的步长来模拟除法。
方案2
这次,我们不减除数了,直接用被除数减去除数的幂次。
被除数 = 除数*2^a + 除数*2^b + ….
例如 47/7 = 7*2^2 + 7*2^1 + 5
答案就是2^2 + 2^1 = 6
这个题目中要注意OverFlow的问题,我们用long做计算,然后比较边界返回特殊情况即可。
代码实现
public int divide(int dividend, int divisor) {
// is positive number
boolean flag = !((dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0));
long ans = ldivide(Math.abs((long)dividend), Math.abs((long)divisor));
ans = flag ? ans : 0 - ans;
if (ans < Integer.MIN_VALUE) {
return Integer.MIN_VALUE;
}
if (ans > Integer.MAX_VALUE) {
return Integer.MAX_VALUE;
}
return (int) ans;
}
private long ldivide(long dividend, long divisor) {
if (divisor == 0) {
return Long.MAX_VALUE;
}
if (dividend == 0 || dividend < divisor) {
return 0;
}
int i = 1;
long k = divisor;
long ans = 0;
while ((k + k) < dividend) {
k = k << 1;
i = i << 1;
}
dividend -= k;
ans += i;
while (dividend > 0) {
while (k > dividend) {
k = k >> 1;
i = i >> 1;
}
dividend -= k;
ans += i;
}
return ans;
}
递归版
public int divide(int dividend, int divisor) {
// is positive number
boolean flag = !((dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0));
long lDividend = Math.abs((long)dividend);
long lDivisor = Math.abs((long)divisor);
if (lDivisor == 0) {
return Integer.MAX_VALUE;
}
if (lDividend == 0 || lDividend < lDivisor) {
return 0;
}
long ans = divideRecursive(lDividend, lDivisor);
ans = flag ? ans : 0 - ans;
if (ans < Integer.MIN_VALUE) {
return Integer.MIN_VALUE;
}
if (ans > Integer.MAX_VALUE) {
return Integer.MAX_VALUE;
}
return (int) ans;
}
private long divideRecursive(long dividend, long divisor) {
if (divisor == 1) {
return dividend;
}
if (dividend < divisor) {
return 0;
}
if (dividend == divisor) {
return 1;
}
int i = 1;
long k = divisor;
int ans = 0;
while ((k + k) < dividend) {
k = k << 1;
i = i << 1;
}
dividend -= k;
ans += i;
ans += divideRecursive(dividend, divisor);
return ans;
}