142. O(1)時(shí)間檢測(cè)2的冪次

用 O(1) 時(shí)間檢測(cè)整數(shù) n 是否是 2 的冪次。
樣例
n=4,返回 true;
n=5,返回 false.

除以2

這個(gè)當(dāng)然是很簡(jiǎn)單也最容易想到,int的話可能要除31次才能出來。

統(tǒng)計(jì)1的位數(shù)

這個(gè)也容易想到,如果是2的冪次的話肯定是正的,然后去統(tǒng)計(jì)1的個(gè)數(shù),需要移位和取且操作,和上面的方法差不多。因?yàn)槌?本來就可以通過移位操作完成。

bool checkPowerOf2(int n) {
        int num=0;
        for(int i=0;i<31;i++)
        {
            if((n>>i)&1==1)
            {
                num++;
            }
        }
        return num==1;
       // write your code here
    }

n和n-1取且

這個(gè)是以前檢測(cè)有多少個(gè)1的時(shí)候用到的一種方法,那個(gè)時(shí)候有一個(gè)結(jié)論:n&n-1可以減少一位1,如果用這種方法,那代碼是相當(dāng)簡(jiǎn)單:也符合時(shí)間復(fù)雜度要求。

    bool checkPowerOf2(int n) {
        if(n<=0)
        return false;
     
        return !(n&(n-1));
       // write your code here
    }

還有復(fù)習(xí)一下計(jì)算機(jī)中數(shù)字的表達(dá)形式:

  1. 有符號(hào)數(shù)最高位做符號(hào)位,0為正,1為負(fù)。
  2. 正數(shù)就是按照正常的表示方法。
  3. 負(fù)數(shù)用補(bǔ)碼表示,補(bǔ)碼為反碼加1,反碼是除符號(hào)位外其他位逐位取反。
  4. -0表示當(dāng)前位數(shù)最小的那個(gè)數(shù)。
  5. n位有符號(hào)數(shù)的表示范圍: -2^n-- 2^(n-1)-1
原碼的表示:

    左邊是符號(hào)位,正數(shù)為0,負(fù)數(shù)為1。其他位表示數(shù)值

    【+10】原碼 = 00001010

    【-10】原碼 = 10001010 

    【+0】原碼 = 00000000

    【-0】原碼 = 10000000

  反碼的表示:

    正數(shù)的反碼和原碼相同,負(fù)數(shù)的反碼由原碼除了符號(hào)位的其余位取反(即0表1,1表0)

    【+10】反碼 = 00001010

    【-10】反碼 = 11110101

    【+0】反碼 = 00000000

    【-0】反碼 = 11111111

  補(bǔ)碼的表示:

    正數(shù)的補(bǔ)碼與原碼相同,負(fù)數(shù)的補(bǔ)碼由原碼的反碼加1得到

    【+10】補(bǔ)碼 = 00001010

    【-10】補(bǔ)碼 = 【-10】反碼 + 1 = 11110101 + 1 = 11110110 

    【+0】補(bǔ)碼 = 00000000

    【-0】補(bǔ)碼 = 【-0】反碼 + 1 = 11111111 + 1 = 【1】00000000(mod(256))

補(bǔ)碼的意義:補(bǔ)碼實(shí)際上是一種模運(yùn)算,以時(shí)鐘為例,時(shí)鐘一圈是12個(gè)小時(shí),即時(shí)鐘的模為12。如果當(dāng)前時(shí)刻是3點(diǎn)鐘,在12個(gè)小時(shí)之后時(shí)刻變?yōu)?5點(diǎn),15在模12之后,依然是3點(diǎn)。再如,將3點(diǎn)的時(shí)針調(diào)慢一個(gè)小時(shí),即調(diào)成2點(diǎn),和將時(shí)針向前調(diào)整11個(gè)小時(shí)的效果是一樣的。因此用3-1和(3+11)mod(12)的結(jié)果一樣。補(bǔ)碼在機(jī)器碼中的運(yùn)用主要是用加法元算代替減法運(yùn)算。CPU的加法器簡(jiǎn)單效率高,因此不需要再專門實(shí)現(xiàn)減法器。

在8位字中,我們的模就是2的8次方,即256。例如:
直接減法:01000000(64)— 00001010(10) = 00110110(54)
用補(bǔ)碼代替減法:01000000(64)+(11110110)(246)= 00110110(54)
兩種運(yùn)算結(jié)果是一樣的。

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

相關(guān)閱讀更多精彩內(nèi)容

  • 題目 描述 用 O(1) 時(shí)間檢測(cè)整數(shù) n 是否是 2 的冪次。 樣例 n=4,返回 true;n=5,返回 fa...
    悠揚(yáng)前奏閱讀 319評(píng)論 0 0
  • 本篇文章講解了計(jì)算機(jī)的原碼, 反碼和補(bǔ)碼. 并且進(jìn)行了深入探求了為何要使用反碼和補(bǔ)碼, 以及更進(jìn)一步的論證了為何可...
    yang2yang閱讀 2,477評(píng)論 1 13
  • 因時(shí)差,直到國(guó)內(nèi)中午才驚聞楊絳先生去世的消息。 第一次知道楊先生并不是作為錢鐘書先生的妻子,而是外公老舊書櫥里的《...
    ooBlessyoo閱讀 314評(píng)論 0 1
  • 轉(zhuǎn)眼馬上27了,很多人到了這個(gè)年紀(jì),多少都有點(diǎn)自己的小成就,或是工作,或是家庭,又或是小積蓄。 可是我,除了歲數(shù),...
    趙小zhao閱讀 702評(píng)論 0 0

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