I solved this leetcode question https://leetcode.com/problems/divide-two-integers/ . The goal is to get the quotient of the division of dividend
by divisor
without using a multiplication or division operator. Here is my solution:
def divide(dividend, divisor):
"""
:type dividend: int
:type divisor: int
:rtype: int
"""
sign = [1,-1][(dividend < 0) != (divisor < 0)]
dividend, divisor = abs(dividend), abs(divisor)
res = 0
i = 0
Q = divisor
while dividend >= divisor:
dividend = dividend - Q
Q <<= 1
res += (1 << i)
i+=1
if dividend < Q:
Q = divisor
i = 0
if sign == -1:
res = -res
if res < -2**31 or res > 2**31 -1:
return 2**31 - 1
return res
So I am having trouble analyzing the time complexity of this solution. I know it should be O(log(something))
. Usually for algorithms we say they are O(log(n))
when the input gets divided by 2 at each iteration but here I multiply the divisor
by 2 Q<<= 1
at each iteration so at each step I take a bigger step towards the solution. Obviously if the dividend
is the same for a bigger divisor
my algorithm will be faster. Similarly the bigger the dividend
for the same divisor
we get a slower run time.
My guess is the equation governing the runtime of this algorithm is basically of the form O(dividend/divisor) (duh that's division) with some logs in there to account for me multiplying Q
by 2 at each step Q <<= 1
... I can't figure out what exactly.
EDIT:
When I first posted the question the algorithm I posted is the one below, Alain Merigot's answer is based on that algorithm. The difference between the version on top and that one is for the one above I never have my dividend go below 0 resulting in a faster run time.
def divide(dividend, divisor):
"""
:type dividend: int
:type divisor: int
:rtype: int
"""
sign = [1,-1][(dividend < 0) != (divisor < 0)]
dividend, divisor = abs(dividend), abs(divisor)
res = 0
i = 0
tmp_divisor = divisor
while dividend >= divisor:
old_dividend, old_res = dividend, res
dividend = dividend - tmp_divisor
tmp_divisor <<= 1
res += (1 << i)
i+=1
if dividend < 0:
dividend = old_dividend
res = old_res
tmp_divisor >>= 2
i -= 2
if sign == -1:
res = -res
if res < -2**31 or res > 2**31 -1:
return 2**31 - 1
return res