演算法39--Divide Two Integers
阿新 • • 發佈:2018-11-25
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
利用移位運算來模擬某個數