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