《leetCode》:Divide Two Integers

来源:互联网 发布:良心单机手游 知乎 编辑:程序博客网 时间:2024/06/05 03:59

题目

Divide two integers without using multiplication, division and mod operator.If it is overflow, return MAX_INT.

思路一:报超时错误

/*完成两个数的除法,不能用乘法、除法、和求余运算思路:由于有上面的限制,因此只能用加法和减法来做此题*///函数中第一个参数为:被除数,第二个参数为:除数。//例如:如24÷8=3,中24就为被除数,8为除数/*需要考虑的测试用例:两个数同号1)同为正号 16/4  、4/162)同为负号  -16/(-4),(-4)/(-16)两个数为异号1)(-16)/4,(-16)/32   分子为负数2)16/(-4) ,16/(-32)分子分母为零的情况。如果除数是0,被除数是非零自然数时,商不存在.这是由于任何数乘0都不会得出非零自然数.如果被除数、除数都等于0,在这种情况下,商不唯一,可以是任何数.这是由于任何数乘0都等于0.虽然有这么的测试用例,可以这样转换,将两个数都变成正数来解此题。*/int divide(int dividend, int divisor) {    if(divisor==0&&dividend>0){        return INT_MAX;    }    if(divisor==0&&dividend<0){        return INT_MIN;    }    //这里将0/0=0来考虑。    if(dividend==0){        return 0;    }    int symbol_1=1;    int symbol_2=1;    //将两个数都变为正数    if(dividend<0){        symbol_1=-1;        dividend=-dividend;    }    if(divisor<0){        symbol_2=-1;        divisor=-divisor;    }    if(divisor>dividend){//除数的绝对值大于被除数的绝对值        return 0;    }    if(divisor==dividend){        return symbol_1==symbol_2?1:-1;    }    //除数的绝对值小于等于被除数的绝对值    if(divisor==1){        return symbol_1==symbol_2?dividend:-dividend;    }    int diff=dividend-divisor;    int result=1;    while(diff>divisor){        result++;        diff=diff-divisor;    }    return symbol_1==symbol_2?result:-result;//符号相同输出为result,否则输出-result;}

报超时错误,如下:

思路二

此种思路来源于
https://leetcode.com/discuss/43313/32-times-bit-shift-operation-in-c-with-o-1-solution;
我刚开始也想到了要利用级数来进行求解,但是我不是讲结果展开为幂级数,而是将除数展开为幂级数,因此,写了下代码还是不行,还是报超时错误。
下面的思路确实很好,别人怎么这么聪明了,自己就是想不到,这应该就是差距吧。

具体思路如下:

we assure the factor ret's binary fomula isret = a0 + a1*2 + a2*2^2 + ...... + a29*2^29 + a30*2^30 + a31*2^31; ai = 0 or 1, i = 0......31the dividend B and divisor A is non-negative, thenA(a0 + a1*2 + a2*2^2 + ...... + a29*2^29 + a30*2^30 + a31*2^31) = B; Eq1(1) when Eq1 divided by 2^31, we can get A*a31 = B>>31; then a31 = (B>>31)/A;if (B>>31) > A, then a31 = 1; else a31 = 0;(2) when Eq1 divided by 2^30, we can get A*a30 + A*a30*2 = B>>30; then a30 = ((B>>30) - a30*A*2)/A; and (B>>30) - a31*A*2 can be rewritten by (B-a31*A<<31)>>30, so we make B' = B-a31*A<<31, the formula simplified to a30 = (B'>>30)/Aif (B'>>31) > A, then a30 = 1; else a30 = 0;(3) in the same reason, we can get a29 = ((B-a31*A<<31-a30*A<<30)>>29)/A, we make B'' = B' - a30*A<<30, the formula simplified to a29 = (B''>>29)/A;do the same bit operation 32 times, we can get a31 ..... a0, so we get the ret finally.the C solution with constant time complexity

根据上面的思路实现的代码如下:

int divide(int dividend, int divisor) {    if(divisor==0||(dividend==INT_MIN&&divisor==-1)){//这两种情况产生溢出        return INT_MAX;    }    if(dividend==0){        return 0;    }    bool flag=(dividend>0)^(divisor>0);//用来标识两个数的符号是否是相同的。,相同就为false。    //将两个数都变为正数   unsigned int  B=(dividend>0)?dividend:-dividend;   unsigned int  A=(divisor>0)?divisor:-divisor;    int result=0;    for(int i=31;i>=0;i--){        if((B>>i)>=A){            result=(result<<1)|0x01;//移位之后在低位添加一个1            //更新B            B-=(A<<i);        }        else{            result=(result<<1);        }    }    return flag?-result:result;}
1 0
原创粉丝点击