LeetCode 762. 二进制表示中质数个计算置位

762. 二进制表示中质数个计算置位题解

题目来源:762. 二进制表示中质数个计算置位

2022.04.05 每日一题

LeetCode 题解持续更新中GitHub仓库地址 CSDN博客地址

今天的题目比较简单,查找范围 [left,right]中 1 的个数是质数的个数

法一:模拟

我们最首先想到的方法就是,首先通过位运算找出当前数字 i 中的 1 的个数

然后判断其对应的值是否是质数

class Solution {
public:
    int countPrimeSetBits(int left, int right) {
        // 创建变量统计满足要求的个数
        int res = 0;
        // 遍历范围,开始进行统计
        for (int i = left; i <= right; i++) {
            // 创建变量统计当前数字 i 中 1 的个数
            int cnt = 0;
            int temp = i;
            // 使用位运算进行统计
            while (temp != 0) {
                cnt += (temp & 1);
                temp >>= 1;
            }
            // 如果 统计的个数是质数,结果中就加一
            if (check(cnt)) res++;
        }
        return res;
    }

    // 判断数字 q 是否为 质数
    bool check(int q) {
        // 这里要注意,1 不是质数
        if (q == 1) return false;
        int s = (int) sqrt(q);
        for (int i = 2; i <= s; i++) {
            if (q % i == 0) return false;
        }
        return true;
    }
};
class Solution {
    public int countPrimeSetBits(int left, int right) {
        // 创建变量统计满足要求的个数
        int res = 0;
        // 遍历范围,开始进行统计
        for (int i = left; i <= right; i++) {
            // 创建变量统计当前数字 i 中 1 的个数
            int cnt = 0;
            int temp = i;
            // 使用位运算进行统计
            while (temp != 0) {
                cnt += (temp & 1);
                temp >>= 1;
            }
            // 如果 统计的个数是质数,结果中就加一
            if (check(cnt)) res++;
        }
        return res;
    }

    // 判断数字 q 是否为 质数
    public boolean check(int q) {
        // 这里要注意,1 不是质数
        if (q == 1) return false;
        int s = (int) Math.sqrt(q);
        for (int i = 2; i <= s; i++) {
            if (q % i == 0) return false;
        }
        return true;
    }
}

法二:优化

由题目我们可以知道,我们 right是范围是小于 1 0 6 10^6 106的,因此我们可以使用 20个位的二进制数字来表示,将 20 个位中的质数置为 1,其余的置为 0,可得到数字 mask = 665772 = 1010001010001010110 0 2 \textit{mask}=665772=10100010100010101100_{2} mask=665772=101000101000101011002,我们将数字 i 的 1 的个数统计为 cnt,将 2 c n t 2^ {cnt} 2cnt与 mask 进行 与 操作,如果不为 0 ,则说明其中包含 1 的个数为 质数

class Solution {
public:
    int countPrimeSetBits(int left, int right) {
        // 创建变量统计满足要求的个数
        int res = 0;
        // 遍历范围,开始进行统计
        for (int i = left; i <= right; i++) {
            // 创建变量统计当前数字 i 中 1 的个数
            int cnt = 0;
            int temp = i;
            // 使用位运算进行统计
            while (temp != 0) {
                cnt += (temp & 1);
                temp >>= 1;
            }
            // 如果 统计的个数是质数,结果中就加一
            if (((int) Math.pow(2, cnt) & 665772) != 0) res++;
        }
        return res;
    }
};
class Solution {
    public int countPrimeSetBits(int left, int right) {
        // 创建变量统计满足要求的个数
        int res = 0;
        // 遍历范围,开始进行统计
        for (int i = left; i <= right; i++) {
            // 创建变量统计当前数字 i 中 1 的个数
            int cnt = 0;
            int temp = i;
            // 使用位运算进行统计
            while (temp != 0) {
                cnt += (temp & 1);
                temp >>= 1;
            }
            // 如果 统计的个数是质数,结果中就加一
            if (((int) Math.pow(2, cnt) & 665772) != 0) res++;
        }
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值