思路:做减法,直到被除数<除数。但结果 Time Limit Exceeded
int divide(int dividend, int divisor) {
if(divisor==0) //分母为0
return INT_MAX;
long int lDividend = dividend;
long int lDivisor = divisor;
long int quote=0;
bool pos = (lDividend>=0 && lDivisor>0) || (lDividend<0 && lDivisor<0);
if(dividend==INT_MIN) //handle overflow
{
if(divisor==-1)
return INT_MAX;
else if(divisor == 1)
return INT_MIN;
else if(divisor == INT_MIN)
return 1;
}
lDividend = abs(lDividend);
lDivisor = abs(lDivisor);
while(lDividend >= lDivisor){
lDividend-=lDivisor;
quote++;
}
if(pos && -quote==INT_MIN){
return INT_MAX;
}
return (int) pos?quote:(-quote);
}
思路:任何一个整数可以表示成以2的幂为底的一组基的线性组合,即num=20+21+22+...+2n。基于以上这个公式以及左移一位相当于乘以2,我们先让除数左移直到大于被除数之前得到一个最大的基,移动k位。接下来我们每次尝试减去这个基,如果可以则结果增加加2^k。然后基继续右移迭代,直到基<divisor为止。因为这个方法的迭代次数是按2的幂知道超过结果,所以时间复杂度为O(logn)。
int divide(int dividend, int divisor) {
if(divisor==0) //分母为0
return INT_MAX;
int res = 0;
if(dividend==INT_MIN) //handle overflow
{
if(divisor==-1)
return INT_MAX;
else if(divisor == 1)
return INT_MIN;
else if(divisor == INT_MIN)
return 1;
res = 1;
dividend += abs(divisor);
}
if(divisor==INT_MIN) //handle overflow
return res;
bool isNeg = ((dividend^divisor)>>31!=0)?true:false; //判断两数相乘除的结果
dividend = abs(dividend);
divisor = abs(divisor);
int digit = 0; //标记除数乘了多少次2
//将除数向左移到最大
while(divisor<=(dividend>>1)) //与被除数除2相比,为防止overflow
{
divisor <<= 1;
digit++;
}
while(digit>=0)
{
if(dividend>=divisor)
{
dividend -= divisor;
res += 1<<digit; //除数左移了digit次,商就要加上2^digit
}
divisor >>= 1;
digit--;
}
return isNeg?-res:res;
}
本系列文章,旨在打造LeetCode题目解题方法,帮助和引导同学们开阔学习算法思路,由于个人能力和精力的局限性,也会参考其他网站的代码和思路,如有侵权,请联系本人删除。