题目来源于力扣(LeetCode)
目录
一、题目
题目相关标签:位运算
说明:
L, R
是L <= R
且在[1, 10^6]
中的整数。R - L
的最大值为 10000。
二、解题思路
2.1 手动计算二进制中位 1 个数的方式
-
据题目说明:元素是 10 ^ 6 内的值,即 1000000,其二进制中位 1 的个数最多为 20 位
-
创建 bucket 数组,记录下 20 以内质数索引上元素值为 1
-
遍历数组,手动计算当前元素转换成二进制后位 1 的个数
-
个数的数值为质数时,结果加 1
2.2 Integer.bitCount() 方式
-
据题目说明:元素是 10 ^ 6 内的值,即 1000000,其二进制中位 1 的个数最多为 20 位
-
创建 bucket 数组,记录下 20 以内质数索引上元素值为 1
-
遍历数组,通过
Integer.bitCount()
方法获取当前元素转换成二进制后位 1 的个数 -
个数的数值为质数时,结果加 1
三、代码实现
3.1 手动计算二进制中位 1 个数的方式
public static int countPrimeSetBits(int L, int R) {
// 可能有 20 个 1,取值范围为 1 ~ 10^6
int[] sushuList = {2, 3, 5, 7, 11, 13, 17, 19};
int[] bucket = new int[20];
// 令桶数组中的素数索引为 1
for (int i : sushuList) {
bucket[i] = 1;
}
int count = 0;
for (int i = L; i <= R; i++) {
// 调用方法计算当前遍历元素数值转换成二进制后位 1 的个数
int oneCount = calcOneCount(i);
// 如果位 1 的个数为素数,count 加 1
if (bucket[oneCount] != 0) {
count ++;
}
}
return count;
}
// 计算十进制数值中转换成二进制后位 1 的个数
public static int calcOneCount(int num) {
int count = 0;
while (num > 0) {
if ((num & 1) == 1) {
count ++;
}
num >>= 1;
}
return count;
}
3.2 Integer.bitCount() 方式
public static int countPrimeSetBits2(int L, int R) {
// 0 ~ 20数值作为索引,如果索引为素数,则索引上的数值为 1
int[] sushu = {0, 0, 1, 1, 0,
1, 0, 1, 0, 0,
0, 1, 0, 1, 0,
0, 0, 1, 0, 1, 0};
int res = 0;
for (int i = L; i <= R; i++) {
// 获取数值 i 转换成二进制后位 1 的个数
int t = Integer.bitCount(i);
// 对应 sushu 数组看位 1 的个数是否为素数
res += sushu[t];
}
return res;
}
四、执行用时
4.1 手动计算二进制中位 1 个数的方式
4.2 Integer.bitCount() 方式
五、部分测试用例
public static void main(String[] args) {
int L = 6, R = 10; // output:4
// int L = 10, R = 15; // output:5
int result = countPrimeSetBits(L, R);
System.out.println(result);
}