首页 > 其他分享 >求质数:204. 计数质数

求质数:204. 计数质数

时间:2023-07-13 21:34:45浏览次数:47  
标签:prime count false 204 int 质数 计数 标注

https://leetcode.cn/problems/count-primes/
204 给定整数 n ,返回 所有小于非负整数 n 的质数的数量 。
示例 1:
输入:n = 10
输出:4
解释:小于 10 的质数一共有 4 个, 它们是 2, 3, 5, 7 。

这题如果用对每个数i,让j从2遍历至sqrt(i)是否存在j,使得i % j == 0(被j整除),是最容易的想到的,但会超时。

看了埃拉托斯特尼筛法(Sieve of Eratosthenes,简称埃氏筛法)后,有很多简化和优化的写法,发现有些不易理解,这里提供一个最易理解的,但不是最优的写法:

class Solution {
public:
    int countPrimes(int n) {
        // 对n,遍历1到n的数,偶数肯定不是质数,3、5等质数的倍数肯定不是,全部标注完后剩余的就是质数
        if (n < 2) return 0;
        vector<bool> prime(n, true);
        for (int i = 2; i < n; ++i) { // 从2开始,并标记所有的2的倍数
            // if (i & 1) { // 等价于i%2,如果一直去除2的倍数,这里和下边代码重复了,就省略了
            //     prime[i] = false;
            //     continue;
            // }
            if (prime[i]) { // 如果当前数是质数,其倍数肯定不是质数,标注为false
                for (int j = 2 * i; j < n; j += i) { // 从i的2倍开始,随后3*i、4*i....
                    // 可能会重复赋值标记,如i=3时会标注prime[15]为false,到i=5时还会标记一次
                    prime[j] = false;
                }
            }
        }
        // 全部统计完后,看下还多少true的
        int count = 0;
        for (int i = 2; i < n; ++i) { // 1不是质数,2开始才是
            if (prime[i]) ++count;
        }
        return count;
    }
};

从代码注释可看出,对小于n的数都会对其倍数进行判断,且有重复标注的情况,所以可以此进一步优化,减少遍历次数;如n=10时,i=2时已标注4、6、8,i=3时标注了6、9,剩下2、3、5、7就是质数了,所以4以后就不用遍历了,也就是其他写法里的到达i<=sqrt(n)的写法。

class Solution {
public:
    int countPrimes(int n) {
        if (n < 2) return 0;
        vector<bool> prime(n, true);
        int s = sqrt(n); // 减少循环次数的写法
        for (int i = 2; i <= s; ++i) { // 从2开始,并标记所有的2的倍数
            if (prime[i]) { // 如果当前数是质数,标注其倍数肯定不是质数
                for (int j = 2 * i; j < n; j += i) { // 从i的2倍开始,随后3*i、4*i....
                    // 可能会重复赋值标记,如i=3时会标注prime[15]为false,到i=5时还会标记一次
                    prime[j] = false;
                }
            }
        }
        // 全部统计完后,看下还多少true的
        int count = 0;
        for (int i = 2; i < n; ++i) { // 1不是质数,2开始才是
            if (prime[i]) ++count;
        }
        return count;
    }
};

第一次结果:
image
第二次结果:
image

标签:prime,count,false,204,int,质数,计数,标注
From: https://www.cnblogs.com/UFO-blogs/p/17552225.html

相关文章

  • 图计数类问题·典
    一、无向图定向问题描述:给定一张\(n\)个点,\(m\)条边的的无向图,求给每条边定向后是DAG的方案数,对\(998244353\)取模。数据范围:\(1\len\le20\)。设\(f_S\)表示\(S\)点集中的点在DAG上时的方案数,枚举出度为\(0\)的点集\(T\),\(g(S)\)表示\(S\)能否成为出度......
  • 计数题目总结
    WC2019数树P4463国家集训队calc......
  • [刷题笔记] Luogu P4017 最大食物链计数
    ProblemDescription首先明确,最大食物链指生产者到顶级消费者(即最高营养级),而不是最长的食物链这样,我们就可以将题意转化为:在一张图中,求入度为0的点到出度为0的点路径数量这不妥妥的拓扑排序嘛(这题竟然在dp训练题单里,想了好久的dp)Solution虽说是拓扑排序,但并不完全是。我们......
  • Go--统计数组中重复的元素及重复次数
    代码:packagemainimport("fmt")funcmain(){//创建有重复数值的数组a1:=[]int{1,2,3,1,4,5,2}a2:=[]string{"t1","t2","t1","t3","t5","t3"}//创建maps1:=......
  • 【计数,DP】CF1081G Mergesort Strikes Back
    ProblemLink现有一归并排序算法,但是算法很天才,设了个递归深度上限,如果递归深度到达\(k\)则立即返回。其它部分都和正常归并排序一样,递归中点是\(\lfloor(l+r)/2\rfloor\),归并每次取两边较小者加入结果。给定\(n,k\),求用这个算法对一个均匀随机的排列\(p\)排序后,\(p\)......
  • 计数杂题
    搞一点计数题放在这,看到有意思的计数就更(虽然在组合数学那已经更了好多了)。[CTSC2017]吉夫特给定一个长度为\(n\)的序列\(a\),保证\(a_i\)互不相同。求出有多少个长度大于等于二的序列满足\[\prod_{i=2}^{k}\binom{a_{b_{i-1}}}{a_{b_i}}\bmod2=\binom{a_{b_1}}{a_{......
  • 【计数,DP】ABC306Ex Balance Scale
    ProblemLink现在有\(n\)个球,每个球有一个重量,重量未知。接下来会进行\(m\)次称重,每次给定\(a_i\)和\(b_i\),比较这两个球的重量,结果可能是\(>,=,<\)中的一种。求在所有\(3^m\)个结果中有几种是可能出现的。\(n\le17,m\len(n-1)/2\)。技巧:怎样配容斥系数将\((a_......
  • 按单元格填充颜色或字体颜色统计数据的自定义函数
    参考网络代码,自己写了二个通用的自定义函数,用于统计不同颜色的单元格数值或个数。1FunctionSumColor(rngAsRange,cellColorAsRange,NAsByte)AsDouble23'输入=SumColor(A1:A10,A1,0),其中A1:A10是统计的范围,A1是统计的颜色所在的单元格,0表示按照背景......
  • sat计数问题
    /*先是建图,跑一次缩点建立一个最初的阵营加上0代表认识,1代表不认识ans=0因为划分了两个独立的阵营,所以一次是只能交换一个人的如果对方阵营我只认识一个,并且我认识的哪一个可以来到我的阵营,那么就将两者进行交换(0,1)如果对方阵营的我都不敌对,或不认识,那我就可以直接过......
  • ubuntu2204 ROS2安装
    ubuntu初始环境配置ROS2换源备份原来的文件sudocp/etc/apt/sources.list/etc/apt/sources_init.list换源sudogedit/etc/apt/sources.list#默认注释了源码镜像以提高aptupdate速度,如有需要可自行取消注释debhttps://mirrors.tuna.tsinghua.edu.cn/ubuntu/j......