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

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

题目描述

给定两个整数 LR,找到闭区间 [L, R] 范围内,计算置位位数为质数 的整数个数。

(计算置位位数:二进制表示中 1 的个数)

示例:

复制代码
输入: L = 6, R = 10
输出: 4
解释:
6  (110) -> 2 个 1,2 是质数
7  (111) -> 3 个 1,3 是质数
8 (1000) -> 1 个 1,1 不是质数
9 (1001) -> 2 个 1,2 是质数
10(1010) -> 2 个 1,2 是质数
共计 4 个。

解题思路

题目核心有两个步骤:

  1. 对区间内每个数,统计其二进制中 1 的个数。
  2. 判断该个数是否为质数。

关键点分析

  • 二进制 1 的个数可以通过位运算快速得到:不断右移并检查最低位。
  • 质数判断:由于本题数据范围 L, R <= 10^6,二进制最多有 20 位(2^20 = 1048576),因此 1 的个数最多为 20。我们可以预先将 20 以内的所有质数列出(2, 3, 5, 7, 11, 13, 17, 19),直接查表即可,无需每次判断质数。

代码实现(C++)

cpp 复制代码
class Solution {
public:
    int countPrimeSetBits(int left, int right) {
        unordered_set<int> primes{2, 3, 5, 7, 11, 13, 17, 19}; // 20 以内的所有质数
        int res = 0;
        for (int i = left; i <= right; ++i) {
            int s = 0;
            // 计算 i 的二进制中 1 的个数
            for (int j = i; j; j >>= 1) s += j & 1;
            res += primes.count(s);
        }
        return res;
    }
};

代码解释

  1. 质数集合
    unordered_set<int> primes{2,3,5,7,11,13,17,19};

    因为最大可能置位位数不超过 20,所以预先存储 20 以内的质数,用于 O(1) 判断。

  2. 遍历区间
    for (int i = left; i <= right; ++i) 枚举区间内每个数。

  3. 计算置位位数

    内层循环 for (int j = i; j; j >>= 1)j 不断右移,直到 j 变为 0。
    s += j & 1 每次取最低位(0 或 1)累加到 s 中,最终 s 即为二进制中 1 的个数。

  4. 结果累加
    if (primes.count(s)) ++res;s 是质数,则答案加 1。

复杂度分析

  • 时间复杂度 :区间长度为 n = right - left + 1,每个数需要循环其二进制位数,最多 20 次,因此总时间复杂度为 O(n * 20),即线性时间。
  • 空间复杂度:仅使用了常数大小的额外空间(质数集合)。

总结

本题巧妙之处在于数据范围决定了置位位数有限,因此可以预先列出质数,避免了动态判断质数的开销。位运算统计 1 的个数也是非常基础且高效的技巧

相关推荐
WZ188104638692 小时前
LeetCode第367题
算法·leetcode
季明洵2 小时前
Java实现循环队列、栈实现队列、队列实现栈
java·数据结构·算法··队列
Non importa2 小时前
二分法:算法新手第三道坎
c语言·c++·笔记·qt·学习·算法·leetcode
WZ188104638692 小时前
LeetCode第2368题
算法·leetcode
iAkuya2 小时前
(leetcode)力扣100 74 数组中的第K个最大元素(快速选择\堆)
数据结构·算法·leetcode
云深处@2 小时前
【数据结构】排序
数据结构·算法·排序算法
舟舟亢亢11 小时前
算法总结——二叉树【hot100】(上)
java·开发语言·算法
weixin_4772716912 小时前
根象:树根。基石。基于马王堆帛书《周易》原文及甲骨文还原周朝生活活动现象(《函谷门》原创)
算法·图搜索算法
普通网友12 小时前
多协议网络库设计
开发语言·c++·算法