0 题目
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
意思是不适用除法,乘法,取模,计算两个数相除。
另外,如果越界,返回MAX_INT
1 分析
难点有两个:
- 越界检查
- 只能用加减和位运算
1.1 什么时候会越界
两个有符号数相除
- 当除数是0的时候,越界
- 当被除数是MIN_INT,除数是-1的时候,结果应该是INT_MAX+1.越界 (INT_MAX = -INT_MAX-1),最大值和最小值在绝对值上,最小值是要大1的。
1.2 使用加减计算除法
首相想到的是挨个相减,减一次,结果+1,但是,太慢。
因此需要成倍的减。
int divide(int a, int b)
{
if (b == 0) //判断除数为0,
{
return INT_MAX;
}
if (a == INT_MIN && b == -1) // 因为 INT_MIN 数值上比 INT_MAX 大 1 ,因此 INT_MIN/-1 会越界
{
return INT_MAX;
}
int tmp_ret = 0;
// 这一步判断需要在前面,因为(INT_MIN,INT_MIN)的情况。
if (a == 0)
{
return 0;
}
// 后面需要将 a,b 取绝对值运算,因此不能存在 a== INT_MIN
// b 可以为 INT_MIN ,因为 abs 后 b 仍然等于 INT_MIN,这里没看懂!!!
if (a == INT_MIN)
{
if (b < 0)
{
a -= b;
++tmp_ret;
}
else
{
a += b;
--tmp_ret;
}
}
bool sign = (a < 0 && b < 0) || (a > 0 && b > 0) ? true : false;
a = abs(a);
b = abs(b);
int ret = 0;
int tmp_b = b;
while (a - tmp_b >= 0)
{
int ret_tmp = 1;
while (a - tmp_b > tmp_b)
{
tmp_b += tmp_b;//每次递增
ret_tmp += ret_tmp;
}
a -= tmp_b;
ret += ret_tmp;
tmp_b = b;
}
return sign ? ret + tmp_ret : -ret + tmp_ret;
}
有些步骤是根据调试出来的结果。因此有种投机取巧的感觉。