leetecode29. 兩數(shù)相除

題目描述

QQ截圖20190318133532.png

解題思路:

1.本題不允許采用除法直接計(jì)算。所以我們可以采用加法逼近的方法 。也就是把多少個(gè)除數(shù)相加以后最近接被除數(shù) 則得到的多少個(gè)除數(shù)的這個(gè)數(shù)字就是相除后的商舉例來說,例如 23/3=7 這個(gè)除法我們就是讓 3+3+3+ 。。。。。+3 N個(gè)3相加得到不大于23且最接近23 的的數(shù)字時(shí)候,這個(gè)時(shí)候需要用到的數(shù)字N就是商,這里我們可以看到3X7=21 3X8=24 即商為7 即7個(gè)3累加的時(shí)候最接近23且 余數(shù)2 。

2.如何找到數(shù)字N呢,如果采用一個(gè)循環(huán)不停地做3的累加直到最近接被除數(shù)為止的話這樣可以得到答案但是需要循環(huán) 23/3次復(fù)雜度為O(N)顯然計(jì)算速度太慢。有沒有更快的辦法的呢?可以采用類似折半查找的辦法,這里我們可以用翻倍逼近的辦法來做如下操作。用被除數(shù)不斷地乘上2做數(shù)字的翻倍的操作直到超過被除數(shù)后 ,然后對剩下的余數(shù)做類似操作 ,直至得到的余數(shù)小于被除數(shù)或者為0 回到例子來說 23/3 :
a . 3翻倍:3?2=6 余數(shù)17
b. 再次翻倍 6?2=12 ; 余數(shù)11
c. 再次翻倍128?2=24 此時(shí)24 大于23 了 返回b 此時(shí)3×2^2 余數(shù)為11 加權(quán)值p=2
d 用11/3繼續(xù)上述操作直至余數(shù)小于3 此時(shí)為3×2^1 余數(shù)為5 加權(quán)值p=1,
5/3 繼續(xù)上述操作直至余數(shù)小于3 此時(shí)為3*2^0 余數(shù)為2 此時(shí)循環(huán)結(jié)束 加權(quán)值p=0 每一步得到一個(gè)每一位數(shù)的權(quán)值序列:【2,1,0】
最后商的數(shù)字為2^2 + 2^1 + 2^0 = 4+2+1 =7

具體代碼為

def divide(self, dividend, divisor):
        """
        :type dividend: int
        :type divisor: int
        :rtype: int
        """
        sign = -1 if (divisor>0)^(dividend>0)  else 1
        if abs(dividend)<abs(divisor) : return  0
        if abs(dividend)== abs(divisor) :return sign
        #r 是余數(shù) ,n是除數(shù) bit記錄每一個(gè)加權(quán)位指數(shù)位數(shù)例如
        # 23/3  23=3*2^2+3*2^1 +3*2^0 =21 最后余2 商為2^2+2^1+2^0 = 7 3*7=21 余數(shù)2
        def recurvediv(r,n,bit):
            if r<n :return
            i = 0
            divsor = n
            maxval = 0
            while(divsor<=r):
                if divsor <=r:
                    i+=1
                    maxval = divsor
                divsor<<=1

            r = r-maxval
            bit.append(i)
            recurvediv(r,n,bit)
        res = []
        result = 0
        recurvediv(abs(dividend),abs(divisor),res)
        for i in res:
            result += 2**(i-1)
        result*=sign    
        if result >=-1*2**31 and result <=2**31-1:
            return result
        else:
            return 2**31-1

總結(jié)

采用翻倍的辦法后計(jì)算的循環(huán)的次數(shù)可以N= lg(N/2)+lg(N/4) +.....+lg(1)~O(lg(N)*lg(N))顯然比單個(gè)累加要好很多,本算法采用遞歸最大遞歸嵌套層數(shù)為lg(N/2)所以如果計(jì)算數(shù)字較大應(yīng)考慮遞歸超限制問題??梢粚⑦f歸改為迭代。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容