欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

LeetCode中如何不用加減乘除做加法

這篇文章給大家分享的是有關(guān)LeetCode中如何不用加減乘除做加法的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

成都創(chuàng)新互聯(lián)公司是一家專業(yè)提供洪江企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計、做網(wǎng)站、成都h5網(wǎng)站建設(shè)、小程序制作等業(yè)務(wù)。10年已為洪江眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站制作公司優(yōu)惠進(jìn)行中。

題目描述

寫一個函數(shù),求兩個整數(shù)之和,要求在函數(shù)體內(nèi)不得使用 “+”、“-”、“*”、“/” 四則運(yùn)算符號。

  • a, b 均可能是負(fù)數(shù)或 0
  • 結(jié)果不會溢出 32 位整數(shù)
                 

題目樣例

                 

示例

  • 輸入: a = 1, b = 1
  • 輸出: 2
                 

題目思考

  1. 不能用四則運(yùn)算, 那還能用哪些運(yùn)算符來實現(xiàn)呢?
                 

解決方案

                 
思路
  • 相比昨天的題目                     劍指 Offer 64. 求 1+2+…+n - leetcode 劍指 offer 系列, 這道題目限制少了很多, 至少循環(huán)/條件判斷/位運(yùn)算這些都能用了
  • 我們先來嘗試分析數(shù)字的二進(jìn)制表示, 看看能否用位運(yùn)算來替代加法
  • 如果某一位的兩個數(shù)字都是 1, 那么這一位的加法就會產(chǎn)生進(jìn)位, 所以                     可以用來計算進(jìn)位, 而且顯然進(jìn)位是要左移一位的
  • 接下來考慮如何得到當(dāng)前位的加法結(jié)果.                     異或在兩個數(shù)字都為 1 或者都為 0 的情況下結(jié)果是 0, 否則結(jié)果是 1, 換言之                     異或就是不帶進(jìn)位的加法
  • 將上面兩步結(jié)合在一起, 我們就能把                     a+b 轉(zhuǎn)換成                     ((a&b)<<1)+(a^b), 雖然這里仍然有加號, 但是我們將其置為新的 a 和 b, 循環(huán)這個過程, 直到進(jìn)位變成 0, 這樣最終異或結(jié)果就是兩者之和了
  • 注意最終進(jìn)位一定能變成 0, 這是因為如果有進(jìn)位的話, 進(jìn)位是會不斷左移的, 而題目保證最終結(jié)果不會溢出, 那么經(jīng)過若干次循環(huán)后, 一定會達(dá)到一個不需要進(jìn)位的狀態(tài), 不然無限左移就會溢出了
  • C++/JAVA 等語言分析到這里就 OK 了, 但 python 需要特別處理負(fù)數(shù)問題. 因為 python 的負(fù)數(shù)表示方法不是像其他語言那樣的 32 位補(bǔ)碼, 而是更高位也全是 1, 這樣在處理負(fù)數(shù)的時候必須手動模擬 32 位補(bǔ)碼, 才能正確得出結(jié)果, 不然最后結(jié)果就不滿足 python 正確的負(fù)數(shù)表示方式, 而變成無符號正數(shù)了
  • 所以我們需要先將負(fù)數(shù)轉(zhuǎn)成 32 位補(bǔ)碼 (                     &0xFFFFFFFF, 正數(shù)仍為自身, 負(fù)數(shù)相當(dāng)于 32 位補(bǔ)碼形式, 因為去掉了更高位上的 1), 然后利用上述結(jié)果求完之后, 如果結(jié)果是負(fù)數(shù)(                     >0x7FFFFFFF)的話再轉(zhuǎn)成正常的 python 負(fù)數(shù)表示方式(                     ~(a ^ 0xFFFFFFFF), 即先對低 32 位的取反, 更高位不變, 然后整體再取反, 從而將大于等于 32 位的數(shù)字重新轉(zhuǎn)成 1)
  • 下面代碼額外列出了 Java 版本, 方便大家對比. Java 的負(fù)數(shù)就是 32 位補(bǔ)碼表示, 所以不需要額外進(jìn)行處理
                 
復(fù)雜度
  • 時間復(fù)雜度 O(logN): 最多需要遍歷所有位數(shù), 數(shù)字 N 的位數(shù)為 logN
  • 空間復(fù)雜度 O(1): 只需要維護(hù)常數(shù)個變量
                 
代碼
                 
python 3
class Solution:
    def add(self, a: int, b: int) -> int:
        # 32位數(shù)掩碼
        mask = 0XFFFFFFFF
        # 32位數(shù)的最大正數(shù)
        posMx = 0X7FFFFFFF
        while b != 0:
            # a是不帶進(jìn)位的和, 都要轉(zhuǎn)成32位整數(shù)
            # b是進(jìn)位, 都要轉(zhuǎn)成32位整數(shù)
            # 循環(huán)直到進(jìn)位為0, 那么a就是最終結(jié)果
            smwithoutcarry = (a ^ b) & mask
            carry = ((a & b) << 1) & mask
            a, b = smwithoutcarry, carry
        # 最終如果是32位負(fù)數(shù)的話, 需要將其轉(zhuǎn)回python正常的負(fù)數(shù)表示形式(高于32位的全是1, 而不是32位負(fù)數(shù)那樣更高位全為0), 做法是先對低 32 位的取反, 更高位不變, 然后整體再取反, 從而將大于等于 32 位的數(shù)字重新轉(zhuǎn)成 1
        return a if a <= posMx else ~(a ^ mask)
                                   
Java
class Solution {
    public int add(int a, int b) {
        while (b != 0)
        {
            int smwithoutcarry = a ^ b;
            int carry = (a & b) << 1;
            a = smwithoutcarry;
            b = carry;
        }
        return a;
    }
}

感謝各位的閱讀!關(guān)于“LeetCode中如何不用加減乘除做加法”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

當(dāng)前標(biāo)題:LeetCode中如何不用加減乘除做加法
文章分享:http://chinadenli.net/article30/ppccso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站微信小程序網(wǎng)站制作App開發(fā)網(wǎng)站設(shè)計小程序開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

搜索引擎優(yōu)化