1. 程式人生 > >演算法39--Divide Two Integers

演算法39--Divide Two Integers

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

利用移位運算來模擬某個數