题目描述
给定两个整数 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, 106] 中的整数。
R - L 的最大值为 10000。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/prime-number-of-set-bits-in-binary-representation
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
用不断移位与1的方式计算1的个数,然后判断个数是否为质数
代码详解
普通方法
class Solution {
public int countPrimeSetBits(int L, int R) {
int count = 0; // 记录答案个数
a:for(int i = L; i <= R; ++i) {
int count1 = 0; // 记录1的个数
int temp = i; // 用临时遍历去做移位
while(temp != 0) {
if((temp & 1) == 1) {
++count1;
}
temp = temp >> 1;
}
if(count1 == 0 || count1 == 1) { // 1的个数为0或1个都不能算质数
continue;
}
// 质数判断
for(int j = 2; j <= Math.sqrt(count1); ++j) {
if(count1 % j == 0) {
continue a;
}
}
++count;
}
return count;
}
}
进阶方法
请注意题目描述中标黄的部分,数字最大不超过106,而219<106
,220>106,因此只要拿出20以内的质数即可 (人都傻了)
class Solution {
public int countPrimeSetBits(int L, int R) {
int count = 0;
for(int i = L; i <= R; ++i) {
int count1 = 0;
int temp = i;
while(temp != 0) {
if((temp & 1) == 1) {
++count1;
}
temp = temp >> 1;
}
// 20以内各个质数
if(count1 == 2 || count1 == 3 || count1 == 5 || count1 == 7 || count1 == 11 || count1 == 13 || count1 == 17 || count1 == 19) {
++count;
}
}
return count;
}
}
注意点
- 在看到精简方法前:就这?看到精简方法后:我还是太年轻。