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