原题:29. Divide Two Integers
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
题目大意:不用乘号和除号,取余实现两个数相除
解题思路:
- 刚开始打算直接不停地减,直到把被除数减为0止,担心当数比较大时可能会超时,但还是打算先试一波:
class Solution {
public:
int divide(int dividend, int divisor)
{
if(divisor==0||(dividend==INT_MIN&&divisor==-1))
return INT_MAX;
int sign=((dividend<0)^(divisor>0))?1:-1;
if(dividend<0)
dividend=-dividend;
if(divisor<0)
divisor=-divisor;
int ans=0;
while(dividend-divisor>0)
{
dividend-=divisor;
ans++;
}
if(dividend-divisor==0)
ans++;
ans*=sign;
return ans;
}
};
结果超时,因此得换一个思路,既然不能一个一个减,我们可以一次性减多个
- 对于被除数a和除数b,我们可以先a-b,如果大于0,再a-2b,再a-2(2*b),b每次翻倍,当不能再减后,a-=b;再从a-b开始
比如11/3,先10-3,发现大于0,将3扩大2倍为6,再10-6,发现还是大于0,于是将6扩大2倍即12,再11-12,发现小于0,于是不能再减了,最多可以减到6,即11-6=5,还剩下5,前面翻倍操作进行了2次,相当于减了4次,每翻一倍,操作2次。于是现在用5-3,发现大于0,于是将3扩大2倍为6,而5-6<0,所以只能减3,这里没有进行翻倍,操作了一次;还剩下5-3=2,小于3,此时已经减完了;共减了2+1=3次,即商为3; - 特殊情况:除数为0,返回最大值;当被除数为-2147483648(最小负数),除数为-1,此时商应该是2147483648.但int最大值为2147484647,超限,于是返回最大值。
代码如下:
class Solution {
public:
int divide(int dividend, int divisor)
{
if(divisor==0||(dividend==INT_MIN&&divisor==-1))
return INT_MAX;
int sign=(dividend<0)^(divisor>0)?1:-1;
if(dividend<0)
dividend=-dividend;
if(divisor<0)
divisor=-divisor;
int dividend_1=dividend,divisor_1=divisor;
int step=1,ans=0;
while(dividend_1-divisor>0)
{
divisor_1=divisor;
step=1;
while(dividend_1-(divisor_1<<1)>0)
{
divisor_1<<=1;
step++;
}
dividend_1-=divisor_1;
ans+=(1<<(step-1));
}
if(dividend_1-divisor==0)
ans++;
ans*=sign;
return ans;
}
};