Given two integers dividend
and divisor
, divide two integers without using multiplication, division and mod operator.
Return the quotient after dividing dividend
by divisor
.
The integer division should truncate toward zero.
Example 1:
Input: dividend = 10, divisor = 3
Output: 3
Example 2:
Input: dividend = 7, divisor = -3
Output: -2
Note:
- Both dividend and divisor will be 32-bit signed integers.
- The divisor will never be 0.
- Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−231, 231 − 1]. For the purpose of this problem, assume that your function returns 231 − 1 when the division result overflows.
实现除法,不能使用乘除以及取余运算
最初思路是先确定最终符号,然后转换为两个数的绝对值进行运算,从被除数中不断减去除数,直到被除数小于除数停止,返回最终结果:
class Solution:
def divide(self, dividend, divisor):
"""
:type dividend: int
:type divisor: int
:rtype: int
"""
if dividend==0:
return 0
flag = True
if dividend*divisor<0:
flag = False
dd = abs(dividend)
ds = abs(divisor)
if dd<ds:
return 0
num = 1
tmp = dd-ds
while tmp>ds:
num += 1
tmp = tmp - ds
if flag:
return num
else:
return -num
后来发现超时了:
实现除法,不能使用乘除以及取余运算,如果继续优化可能会使用位运算
换一个角度思考,我们一次取除法的整数次倍数,直到该值刚好不大于被除数,此时倍数即为最终答案,
假设被除数dd 除数ds 商为num 余数为x
有dd=ds*num+x (0<=x<ds) 现在求num的值,考虑num的二进制,假设有n位Mn-1Mn-2....M1M0,即
num=Mn-1*pow(2,n-1)+.....+M1*pow(2,1)+M0*pow(2,0)
先求出n-1的值 利用ds不断左移直到刚好不大于dd,此时移动的位数即为n-1,dd=dd-ds*pow(2,n-1)继续执行上述过程求出n-2。。。。
最终结果有:num=Mn-1*pow(2,n-1)+.....+M1*pow(2,1)+M0*pow(2,0)
class Solution:
def divide(self, dividend, divisor):
"""
:type dividend: int
:type divisor: int
:rtype: int
"""
maxv = pow(2,31)-1
minv = -pow(2,31)
if dividend==0:
return 0
flag = True
if dividend*divisor<0:
flag = False
dd = abs(dividend)
ds = abs(divisor)
num = 0
tmp = ds
while dd>=ds:
m = 1
tmp = ds
while dd>(tmp<<1):
tmp = tmp << 1
m = m << 1
num += m
dd -= tmp
if flag:
return num if num<=maxv else maxv
else:
return -num if -num>=minv else minv
利用移位运算来模拟某个数