題目:
給定兩個整數,被除數 dividend 和除數 divisor。將兩數相除,要求不使用乘法、除法和 mod 運算子。
返回被除數 dividend 除以除數 divisor 得到的商。
整數除法的結果應當截去(truncate)其小數部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
示例 1:
輸入: dividend = 10, divisor = 3
輸出: 3
解釋: 10/3 = truncate(3.33333..) = truncate(3) = 3
示例 2:
輸入: dividend = 7, divisor = -3
輸出: -2
解釋: 7/-3 = truncate(-2.33333..) = -2
被除數和除數均為 32 位有符號整數。
除數不為 0。
假設我們的環境只能儲存 32 位有符號整數,其數值範圍是 [−231, 231 − 1]。本題中,如果除法結果溢位,則返回 231 − 1。
思路:
既然不能用乘除法,可以換種思路,除法乘法其實就是變相的加減法。
我們可以從被除數減去除數,記錄經歷多少個multiple因子,即為我們需要的結果
方法一:
位運算輔助,核心思想是通過減法,同時倍增倍減因子模擬實現除法功能。
class solution(object):
def divide(self, dividend, divisor):
""":type dividend: int
:type divisor: int
:rtype: int
"""res = 0
min_int, max_int = -2147483648, 2147483647 # [−2**31, 2**31−1]
flag = 1 if dividend ^ divisor >= 0 else -1 #異或用來判斷正負
dividend = (dividend + (dividend>>31))^(dividend>>31) #取絕對值
divisor = (divisor + (divisor>>31))^(divisor>>31) #取絕對值
res = 0
while dividend >= divisor:
cur,multiple = divisor,1
while dividend >= cur:
dividend -=cur
res +=multiple
multiple <<=1
cur <<=1
if flag<0:
res = ~res +1 #取相反數
return min(max(min_int, res), max_int)
方法二:
記錄一下orust題解的思路。
兩種方法同一種思路,只不過不是用位運算進行操作。
遞迴:
class solution(object):
def divide(self, dividend, divisor):
""":type dividend: int
:type divisor: int
:rtype: int
"""min_int, max_int = -2147483648, 2147483647 # [−2**31, 2**31−1]
flag = 1 # 儲存正負號,並將分子分母轉化為正數
if dividend < 0: flag, dividend = -flag, -dividend
if divisor < 0: flag, divisor = -flag, -divisor
def div(dividend, divisor):
if dividend < divisor:
return 0
cur = divisor
multiple = 1
while cur + cur < dividend: # 用加法求出保證divisor * multiple <= dividend的最大multiple
cur += cur # 即cur分別乘以1, 2, 4, 8, 16...2^n,即二進位制搜尋
multiple += multiple
return multiple + div(dividend - cur, divisor)
res = div(dividend, divisor)
res = res if flag > 0 else -res # 恢復正負號
if res < min_int: # 根據是否溢位返回結果
return min_int
elif min_int <= res <= max_int:
return res
else:
return max_int
迭代:
class solution(object):
def divide(self, dividend, divisor):
""":type dividend: int
:type divisor: int
:rtype: int
"""min_int, max_int = -2147483648, 2147483647
flag = 1
if dividend < 0:
flag, dividend = -flag, -dividend
if divisor < 0:
flag, divisor = -flag, -divisor
res = 0
while dividend >= divisor:
cur = divisor #第一次是cur = divisor
multiple = 1
while cur+cur < dividend:
cur += cur # 直接比較divisor x 2(加快比較速度)
multiple += multiple # 保留divisor的倍數,也就是我們需要累加的商
dividend -= cur # dividend 減除數divisor 進行下一輪while
res += multiple
res = res if flag >0 else -res #還原商的正負
if res < min_int:
return min_int
elif res > max_int:
return max_int
else:
return res
LeetCode29 兩數相除
給定兩個整數,被除數dividend和除數divisor。將兩數相除,要求不使用乘法 除法和 mod 運算子。返回被除數dividend除以除數divisor得到的商。示例 1 輸入 dividend 10,divisor 3輸出 3示例 2 輸入 dividend 7,divisor 3輸出 2說...
LeetCode 29 兩數相除
給定兩個整數,被除數dividend和除數divisor。將兩數相除,要求不使用乘法 除法和 mod 運算子。返回被除數dividend除以除數divisor得到的商。示例 1 輸入 dividend 10,divisor 3 輸出 3 示例 2 輸入 dividend 7,divisor 3 輸出...
leetcode 29 兩數相除
給定兩個整數,被除數dividend和除數divisor。將兩數相除,要求不使用乘法 除法和 mod 運算子。返回被除數dividend除以除數divisor得到的商。示例 1 輸入 dividend 10,divisor 3輸出 3示例 2 輸入 dividend 7,divisor 3輸出 2說...