leetCode 191. Number of 1 Bits

    題目鏈接:https://leetcode.com/problems/number-of-1-bits/

    題目內容:

Write a function that takes an unsigned integer and returns the number of ’1' bits it has (also known as the Hamming weight).

For example, the 32-bit integer ’11' has binary representation 00000000000000000000000000001011, so the function should return 3.

    題目分析:

    這道題我選擇當一回《編程之美》的搬運工,在“求二進制數中1的個數”這一節有詳細的說明。

    1> 首先是我自己的一種解法,定義一個uint_t的變量作爲測試位,初始化爲1,即00000000000000000000000000000001,用移位的方式測試給定數的每一位,並加到計數器中。其中要取得給定數n在某一位上的數字,還需要將測試位和n的“與操作”的結果做一個移位,所以的數目爲迭代的次數。具體如代碼所示

class Solution {
public:
    int hammingWeight(uint32_t n) {
    	int count = 0;
    	uint32_t test = 1;
    	for(int i=0;i<32;i++) {
    	    count += (n&test) >> i;
    	    test <<= 1;
    	}
    	return count;
    }
};

    2> 上述運行的結果是8ms,但是其實沒什麼必要定義一個測試位,只要每次讓給定數n右移,並與0x01做“與操作”就能得到每一位上的數字,這就是《編程之美》上面的解法二,測試了下,的確要快了一些,用了4ms,至少在這道題上是這樣。

int count = 0;
for (int i = 0; i < 32; i++) {
    count += n&0x01;
    n >>= 1;
   }
return count;
    3> 下面祭出編美里的第一種解法,其實也是最容易想到的,編美上第一種解法往往不是最好的,從分析來看的確是這樣,通過除法和取餘的操作肯定比位運行慢,因爲bit纔是計算機最喜歡的語言。原理是這樣的,每次對n取餘,這樣的結果肯定就是最後一位的數字,用計數器加起來,這樣之後將n除以2,表示往右移了一位。比較打臉的是,該解法的在這道題的運行速度上也是4ms。

int count = 0;
    while(n) {
        if(n % 2 == 1)
    	    count++;
    	n /= 2;
    }
    	return count;

    4> 按照編美上面的解釋,也的確有道理,有些零的位沒必要做測試或者累加操作,只計算當前的某一個1就行了,直接貼出解法。

int count = 0;
    while(n) {
    	count++;
    	n &= (n-1);
    }
return count;


    又一次打臉的是,這個解法也是用了8ms。。。當然,編美上面還有傳統的暴力打表法,向來是oj中最爲不恥但是效率最好的,畢竟下標O(1)啊。

    補充一下:在這道題中已經指明瞭是unsigned int,因此是不用考慮負數的。假設輸入的參數中規定是整數,即n可能爲負數,這時候解法2就失效了,因爲對於帶符號的整數右移,如果整數n是正數,右移的時候會在最左也就是最高位補0,這沒問題;如果n是負數,爲了保證右移後還是負數,右移的時候會在最左也就是最高位補1,這樣最後整個數變成0XFFFF而導致死循環,因此要根據輸入的類型選擇算法,按照編美和劍指offer的推薦首選解法4.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章