class Solution:
def countPrimeSetBits(self, left: int, right: int) -> int:
def is_prime(n):
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
primes = {2, 3, 5, 7, 11, 13, 17, 19}
count = 0
for num in range(left, right + 1):
set_bits = bin(num).count('1')
if set_bits in primes:
count += 1
return count
class Solution {
public:
bool isPrime(int n) {
if (n < 2) return false;
for (int i = 2; i * i <= n; ++i) {
if (n % i == 0) return false;
}
return true;
}
int countPrimeSetBits(int left, int right) {
int primes[] = {2, 3, 5, 7, 11, 13, 17, 19};
std::unordered_set<int> primeSet(primes, primes + 8);
int count = 0;
for (int num = left; num <= right; ++num) {
int setBits = __builtin_popcount(num);
if (primeSet.count(setBits)) {
++count;
}
}
return count;
}
};
class Solution {
public int countPrimeSetBits(int left, int right) {
int[] primes = {2, 3, 5, 7, 11, 13, 17, 19};
Set<Integer> primeSet = new HashSet<>();
for (int p : primes) primeSet.add(p);
int count = 0;
for (int num = left; num <= right; num++) {
int setBits = Integer.bitCount(num);
if (primeSet.contains(setBits)) {
count++;
}
}
return count;
}
}
var countPrimeSetBits = function(left, right) {
const primes = new Set([2, 3, 5, 7, 11, 13, 17, 19]);
let count = 0;
for (let num = left; num <= right; num++) {
let setBits = num.toString(2).split('1').length - 1;
if (primes.has(setBits)) {
count++;
}
}
return count;
};
The problem asks you to count how many numbers in a given range, from left
to right
(inclusive), have a prime number of set bits in their binary representation.
A set bit is a bit with value 1. For each integer in the range, you convert it to binary, count the number of 1's (set bits), and check if that count is a prime number. If it is, you increment your answer.
Constraints:
left
and right
.
At first glance, the problem seems to require checking each number in the range, converting it to binary, counting the set bits, and then checking if that count is a prime number. This approach is straightforward but could be slow if the range is large.
To optimize, we can make two observations:
right
(which is at most 20 for the problem's constraints).Let's break down the optimized solution step by step:
left
to right
(inclusive).bin(num).count('1')
in Python).
Let's walk through an example with left = 6
and right = 10
:
110
(2 set bits). 2 is prime. Count = 1111
(3 set bits). 3 is prime. Count = 21000
(1 set bit). 1 is not prime. Count = 21001
(2 set bits). 2 is prime. Count = 31010
(2 set bits). 2 is prime. Count = 4Brute-force Approach:
The key insight in this problem is recognizing that the number of set bits is always small, so we can precompute which counts are prime and check them quickly. By iterating through the range, counting set bits efficiently, and using a set for primality lookup, we achieve an elegant and highly efficient solution. This approach avoids unnecessary computation and leverages language features for clean, readable code.