Prime Number of Set Bits in Binary Representation
Link
Description
Given two integers left
and right
, return the count of numbers in the inclusive range [left, right]
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 1
's present when written in binary.
For example, 21
written in binary is 10101
, which has 3
set bits.
Example 1:
- Input:
left = 6, right = 10
- Output:
4
- Explanation:
| 6 -> 110 (2 set bits, 2 is prime)
7 -> 111 (3 set bits, 3 is prime)
8 -> 1000 (1 set bit, 1 is not prime)
9 -> 1001 (2 set bits, 2 is prime)
10 -> 1010 (2 set bits, 2 is prime)
4 numbers have a prime number of set bits.
|
Example 2:
- Input:
left = 10, right = 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)
5 numbers have a prime number of set bits.
|
Constraints:
1 <= left <= right <= 10^6
0 <= right - left <= 10^4
Solution
Way 1
| class Solution {
private:
bool isPrime(int x) {
if (x < 2) return false;
for (int i = 2; i <= x / i; i++) {
if (x % i == 0) return false;
}
return true;
}
int bitCount(int x) {
int cnt = 0;
while (x) {
cnt += x & 1;
x >>= 1;
}
return cnt;
}
public:
int countPrimeSetBits(int left, int right) {
int res = 0;
for (int i = left; i <= right; i++) {
if (isPrime(bitCount(i))) res++;
}
return res;
}
};
|
Using the built-in function (see reference):
| class Solution {
private:
bool isPrime(int x) {
if (x < 2) return false;
for (int i = 2; i <= x / i; i++) {
if (x % i == 0) return false;
}
return true;
}
public:
int countPrimeSetBits(int left, int right) {
int res = 0;
for (int i = left; i <= right; i++) {
if (isPrime(__builtin_popcount(i))) res++;
}
return res;
}
};
|
- Time complexity: \(O\left( \left( right-left \right) \cdot \sqrt{\log right} \right)\);
- Space complexity: \(O(1)\).
Way 2
| class Solution {
public:
int countPrimeSetBits(int left, int right) {
unordered_set<int> primes({2, 3, 5, 7, 11, 13, 17, 19});
int res = 0;
for (int i = left; i <= right; i++) {
int s = 0;
for (int k = i; k; k >>= 1) s += k & 1;
if (primes.count(s)) res++;
}
return res;
}
};
|
Way 3
See reference.
| class Solution {
public:
int countPrimeSetBits(int left, int right) {
string bin("10100010100010101100");
int mask = stoi(bin, nullptr, 2);
int res = 0;
for (int i = left; i <= right; i++) {
if ((1 << __builtin_popcount(i)) & mask) res++;
}
return res;
}
};
|
- Time complexity: \(O(right-left)\);
- Space complexity: \(O(1)\).