[LeetCode] Prime Number of Set Bits in Binary Representation 二進制表示中的非零位個數為質數


 

Given two integers L and R, find the count of numbers in the range [L, R] (inclusive) having a prime number of set bits in their binary representation.

(Recall that the number of set bits an integer has is the number of 1s present when written in binary. For example, 21 written in binary is 10101 which has 3 set bits. Also, 1 is not a prime.)

 

Example 1:

Input: L = 6, R = 10
Output: 4
Explanation:
6 -> 110 (2 set bits, 2 is prime)
7 -> 111 (3 set bits, 3 is prime)
9 -> 1001 (2 set bits , 2 is prime)
10->1010 (2 set bits , 2 is prime)

 

Example 2:

Input: L = 10, R = 15
Output: 5
Explanation:
10 -> 1010 (2 set bits, 2 is prime)
11 -> 1011 (3 set bits, 3 is prime)
12 -> 1100 (2 set bits, 2 is prime)
13 -> 1101 (3 set bits, 3 is prime)
14 -> 1110 (3 set bits, 3 is prime)
15 -> 1111 (4 set bits, 4 is not prime)

 

Note:

  1. L, R will be integers L <= R in the range [1, 10^6].
  2. R - L will be at most 10000.

 

這道題給了我們一個整數范圍[L, R],讓我們統計其中有多個整數,其二進制表示中非零位個數為質數。參考題目中的例子不難理解題意,那么博主最先想到的就是暴力搜索啊,畢竟是到Easy題嘛,可能不需要太多的技巧。我們遍歷整數范圍[L, R]中的每一個數字,然后先統計出所有非零位個數cnt,通過和1相與,再右移一位的方式。然后就是來判斷這個cnt是否是質數,判斷的方法就是就是從其平方開始,一個一個的除,如果一直到2都沒有約數,那么就是質數啦,結果res累加1,參見代碼如下:

 

解法一:

class Solution {
public:
    int countPrimeSetBits(int L, int R) {
        int res = 0;
        for (int i = L; i <= R; ++i) {
            int t = i, cnt = 0;
            while (t > 0) {
                if (t & 1 == 1) ++cnt;
                t >>= 1;
            }
            bool succ = true;
            for (int j = sqrt(cnt); j > 1; --j) {
                if (cnt % j == 0) {
                    succ = false; break;
                }
            }
            if (succ && cnt != 1) ++res;
        }
        return res;
    }
};

 

好,下面我們來優化一下上面的解法,由於題目中給了數的大小范圍 R <= 106 < 220,那么我們統計出來的非零位個數cnt只需要檢測是否是20以內的質數即可,所以我們將20以內的質數都放入一個HashSet中,然后統計出來cnt后,直接在HashSet中查找有沒有即可,參見代碼如下:

 

解法二:

class Solution {
public:
    int countPrimeSetBits(int L, int R) {
        int res = 0;
        unordered_set<int> primes{2, 3, 5, 7, 11, 13, 17, 19};
        for (int i = L; i <= R; ++i) {
            int cnt = 0;
            for (int j = i; j > 0; j >>= 1) {
                cnt += j & 1;
            }
            res += primes.count(cnt);
        }
        return res;
    }
};

 

下面這種寫法就更簡潔啦,直接使用了C++的內置函數__builtin_popcount來快速的求出非零位的個數cnt,然后又利用到了20以內的數,只要不能被2和3的一定是質數,又可以快速判斷了質數了,參見代碼如下:

 

解法三:

class Solution {
public:
    int countPrimeSetBits(int L, int R) {
        int res = 0;
        for (int i = L; i <= R; ++i) {
            int cnt = __builtin_popcount(i);
            res += cnt < 4 ? cnt > 1 : (cnt % 2 && cnt % 3);
        }
        return res;
    }
};

 

類似題目:

Number of 1 Bits

 

參考資料:

https://leetcode.com/problems/prime-number-of-set-bits-in-binary-representation/discuss/113225/Short-C++-12-ms

https://leetcode.com/problems/prime-number-of-set-bits-in-binary-representation/discuss/113227/JavaC++-Clean-Code

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM