leetcode 每日一题 29. 两数相除

 

移位减法

思路:

以十进制除法为例,我们可以通过不断用被除数减去除数直到为负值为止,记录减的次数即为对应结果。但是如果是一个很大的被除数和一个很小的除数,这个时候要循环减除数耗时间过长效率很低。计算机中记录数字采用二进制法,所以我们可以采用移位的办法来提高效率。这里假设除数被除数均为正数,我们对除数进行左移,直到大于被除数为止。接着再进行右移,右移的同时如果被除数大于除数则减去除数记录对应移位的结果,然后用减过后的被除数继续循环,最后即可的到最终结果。

例如:

30 /  3 

30 二进制  11110

2  二进制   11

商为 0

我们对 11进行移位直到大于11110 => 即 110000  这里我们移动了count=4位

接着我们对110000进行右移得 11000 ,此时 被除数 11110 > 11000 ,则被除数=11110 - 11000 = 110 ,商=0+8->[ 2**(4-1)] = 8

接着对11000进行右移得1100,此时被除数 110 < 1000 ,则继续下一步

接着对1100进行右移得110,此时被除数 110 = 110 ,则 被除数 = 110 - 110 = 0 ,商=8+2->[ 2**(2-1)] = 10

接着对110进行右移得11,此时被除数 0 < 10 ,则循环结束

此时得到最终结果商为10

代码:

class Solution:
    def divide(self, dividend: int, divisor: int) -> int:
        sign = (dividend > 0) ^ (divisor > 0)
        dividend = abs(dividend)
        divisor = abs(divisor)
        count = 0
        while dividend >= divisor:
            count += 1
            divisor <<= 1
        result = 0
        while count > 0:
            count -= 1
            divisor >>= 1
            if divisor <= dividend:
                result += 1 << count 
                dividend -= divisor
        if sign: result = -result
        return result if -(1<<31) <= result <= (1<<31)-1 else (1<<31)-1 

 

 

 

posted @ 2020-05-11 11:26  nil_f  阅读(139)  评论(0编辑  收藏  举报