一、题目
给定两个整数 L
和 R
,找到闭区间 [L, R]
范围内,计算置位位数为质数的整数个数。
(注意,计算置位代表二进制表示中1的个数。例如 21
的二进制表示 10101
有 3 个计算置位。还有,1 不是质数。)
示例 1:
输入: L = 6, R = 10
输出: 4
解释:
6 -> 110 (2 个计算置位,2 是质数)
7 -> 111 (3 个计算置位,3 是质数)
9 -> 1001 (2 个计算置位,2 是质数)
10-> 1010 (2 个计算置位,2 是质数)
示例 2:
输入: L = 10, R = 15
输出: 5
解释:
10 -> 1010 (2 个计算置位, 2 是质数)
11 -> 1011 (3 个计算置位, 3 是质数)
12 -> 1100 (2 个计算置位, 2 是质数)
13 -> 1101 (3 个计算置位, 3 是质数)
14 -> 1110 (3 个计算置位, 3 是质数)
15 -> 1111 (4 个计算置位, 4 不是质数)
注意:
L, R
是L <= R
且在[1, 10^6]
中的整数。R - L
的最大值为 10000。
二、题解思路
- 题解思路:先将十进制数转换成二进制(使用bitset),然后计算二进制中1的个数(使用count()),判断这个个数是否为质数,为质数则总数加一。
- 质数判断:对于每个需要判断的数n,其实并不需要从2判断到n-1,我们知道,一个数若可以进行因数分解,那么分解时得到的两个数一定是一个小于等于sqrt(n),一个大于等于sqrt(n),据此,上述代码中并不需要遍历到n-1,遍历到sqrt(n)即可,即2到sqrt(n)。
if(n <=3) //1不是质数,2、3都是质数
return n>1;
else
{
for(int j = 2;j <=sqrt(n);j++) //判断n是否为质数
{
if(n % j == 0)
return false;
}
return true;
}
三、代码实现
- C++代码实现
class Solution {
public:
int countPrimeSetBits(int L, int R)
{
int counts = 0; //置位位数为质数的整数个数
for(int i =L;i<=R;i++)
{
bitset<32> b(i); //将十进制转换成二进制
if(number_dector(b.count())) //bitset中的count()是计算二进制中1的个数
counts++;
}
return counts;
}
bool number_dector(int n) //判断n是否为质数(素数)
{
if(n <=3) //1不是质数,2、3都是质数
return n>1;
else
{
for(int j = 2;j <=sqrt(n);j++) //判断n是否为质数
{
if(n % j == 0)
return false;
}
return true;
}
}
};
四、知识点学习
1、C++的bitset类的用法
2、判断一个数是否为质数(素数)