-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdivide-two-integers.py
81 lines (74 loc) · 2.57 KB
/
divide-two-integers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# 29. Divide Two Integers
# 🟠 Medium
#
# https://leetcode.com/problems/divide-two-integers/
#
# Tags: Math - Bit Manipulation
import timeit
# This solution is based on the fact that the quotient of a division is
# equal to the number of times the divisor goes into the dividend.
# We can use bitwise operations to get the quotient.
#
# Time complexity: O(log2(n)) - In each iteration we divide the initial
# dividend by 2.
# Space complexity: O(1) - We only store integer values.
#
# Runtime 50 ms Beats 9.81%
# Memory 16.4 MB Beats 11.94%
class Solution:
def divide(self, dividend: int, divisor: int) -> int:
# Determine if the result will be negative
negative = (dividend > 0 and divisor < 0) or (
dividend < 0 and divisor > 0
)
# The problem has a constraint of -2147483648 to 2147483647
upper_bound = 1 << 31 if negative else (1 << 31) - 1
# Equivalent to using abs()
dividend = 0 - dividend if dividend < 0 else dividend
divisor = 0 - divisor if divisor < 0 else divisor
# Convert the dividend to a binary list
dividend = [int(x) for x in bin(dividend)[2:]]
current_dividend = 0
result = 0
for next_digit in dividend:
current_dividend = (current_dividend << 1) + next_digit
if divisor <= current_dividend:
current_dividend -= divisor
new_digit = 1
else:
new_digit = 0
result = (result << 1) + new_digit
result = min(result, upper_bound)
if negative:
result = 0 - result
return result
def test():
MIN_ALLOWED = -2147483648
MAX_ALLOWED = 2147483647
executors = [Solution]
tests = [
[1, 1, 1],
[0, 1, 0],
[10, 3, 3],
[7, -3, -2],
[1 << 31, 1, MAX_ALLOWED],
[1 << 31, -17, -126322567],
[MIN_ALLOWED, -1, MAX_ALLOWED],
]
for executor in executors:
start = timeit.default_timer()
for _ in range(1):
for col, t in enumerate(tests):
sol = executor()
result = sol.divide(t[0], t[1])
exp = t[2]
assert result == exp, (
f"\033[93m» {result} <> {exp}\033[91m for"
+ f" test {col} using \033[1m{executor.__name__}"
)
stop = timeit.default_timer()
used = str(round(stop - start, 5))
cols = "{0:20}{1:10}{2:10}"
res = cols.format(executor.__name__, used, "seconds")
print(f"\033[92m» {res}\033[0m")
test()