LeetCode 第 204 题 (Count Primes)

LeetCode 第 204 题 (Count Primes)

Description:

Count the number of prime numbers less than a non-negative number, n.

计算小于 N 的素数的个数。这道题目比较简单。但是想提高计算效率与需要费点脑筋。

判断一个数字 n 是不是素数的简单方法是 用 n 去除 2,3,4,…,n?1,如果都不能整除就说明这个数是素数。

按照这个思路可以写个简单的函数。

 bool isPrime(int n)
{
    if(n < 1) return false;
    for (int i = 2; i < n; i++)
    {
          if (num % i == 0)
          {
              return false;
          }
    }
    return true;
}

这个代码还可以优化一点。不用除到 n?1,只要除到 [n??√] 就可以了。

bool isPrime(int n)
{
    if(n < 1) return false;
    for (int i = 2; i * i < n; i++)
    {
          if (num % i == 0)
          {
              return false;
          }
    }
    return true;
}

这个代码每次判断时都要算一遍 i?i,而第 69 题给出了一个计算 [n??√] 的快速算法,利用这个算法还可以再优化一点。

 int mySqrt(int x)
{
    if(x <= 0) return 0;
    int a1 = 1;
    int a2 = 46341 * 2 - 1;
    unsigned int a, y;
    if(a2 > x / 2) a2 = x;
    do
    {
        a = (a1 + a2) / 2;
        y = a * a;
        if(y == x) return a;
        if(y > x)
        {
            a2 = a;
        }
        else
        {
            a1 = a;
        }
    }while(a1 + 1 < a2);
    a = (a1 + a2) / 2;
    return a;
}
 bool isPrime(int n)
{
    if(n < 1) return false;
    int sn = mySqrt(n);
    for (int i = 2; i <= sn; i++)
    {
          if (num % i == 0)
          {
              return false;
          }
    }
    return true;
}

之后计算素数个数的代码就可以写成这样。

int countPrimes(int n)
{
   int count = 0;
   for (int i = 1; i < n; i++)
   {
      if (isPrime(i)) count++;
   }
   return count;
}

即使写成这样,这个代码的计算复杂度还是有点大,isPrime 函数的时间复杂度是 O(n??√),countPrimes 函数的时间复杂度是 O(n),所以整体的复杂度是 O(nn??√)。

实际上有一种简单的算法,时间复杂度可以降低到 O(nlog(log(n)))。这种方法就是所谓的 Eratosthenes 筛选法(Sieve of Eratosthenes)。首先建立一张有 n 个元素的大表,表中每个元素都标记为 1。那么这个表中 2 是第一个素数,2 的倍数都不是素数,那么把表中 2 的倍数都标记为 0。之后找表中在 2 后面第一个元素值为 1 的元素,这个元素就是第二个素数,当然这个数是 3,然后再将表中3 的倍数全部标记为 0。重复这个过程,就可以将表中所有的素数找出来了。按照这个思路写的代码如下:

int countPrimes(int n)
{
    bool *primeTable = new bool[n];

    for (int i = 0; i < n; i++)
    {
        primeTable[i] = true;
    }

    int i = 2;
    int count = 0;
    while (i * i < n)
    {
        if (primeTable[i])
        {
            count++;
            for (int j = i * i; j < n; j += i)
            {
                primeTable[j] = false;
            }
        }
        i++;
    }
    while (i < n)
    {
        if(primeTable[i])
        {
            count++;
        }
        i++;
    }
    delete[] primeTable;
    return count;
}

除此之外,还有更快的判段一个数是否是素数的方法,时间复杂度为 O(1)。不过那种算法属于概率算法,有一定的小概率出错,以后有时间单独写一篇博客介绍那些方法。

时间: 2024-08-02 10:57:54

LeetCode 第 204 题 (Count Primes)的相关文章

leetcode第38题-Count and Say

The count-and-say sequence is the sequence of integers beginning as follows: 1, 11, 21, 1211, 111221, ... 1 is read off as "one 1" or 11. 11 is read off as "two 1s" or 21. 21 is read off as "one 2, then one 1" or 1211. Given

Leetcode(59)-Count Primes

题目: Description: Count the number of prime numbers less than a non-negative number, n. 思路: 题意:求小于给定非负数n的质数个数 西元前250年,希腊数学家厄拉多塞(Eeatosthese)想到了一个非常美妙的质数筛法,减少了逐一检查每个数的的步骤,可以比较简单的从一大堆数字之中,筛选出质数来,这方法被称作厄拉多塞筛法(Sieve of Eeatosthese). 具体操作:先将 2~n 的各个数放入表中,然

Count Primes Total Accepted: 831 Total Submissions: 6167

题目来自:Leetcode https://leetcode.com/problems/count-primes/ Count Primes Total Accepted: 831 Total Submissions: 6167My Submissions Question  Solution Description: Count the number of prime numbers less than a non-negative number, n Hint: The number n c

leetcode 204/187/205 Count Primes/Repeated DNA Sequences/Isomorphic Strings

一:leetcode 204 Count Primes 题目: Description: Count the number of prime numbers less than a non-negative number, n 分析:此题的算法源码可以参看这里,http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes 代码: class Solution { public: int countPrimes(int n) { // 求小于一个数n的素数个

LeetCode:Count Primes - 统计质数数量

1.题目名称 Count Primes(统计质数数量) 2.题目地址 https://leetcode.com/problems/count-primes/ 3.题目内容 英文:Count the number of prime numbers less than a non-negative number, n. 中文:统计正整数n以内(不含n本身)质数的数量 4.一个TLE的方法 从1到n,考察每个数字是否为质数.这个方法由于花费时间较长,不能满足题目中对时间的要求. 一段实现此方法的Jav

Leetcode problem-204 Count Primes 题解

Leetcode problem-204 Count Primes Count the number of prime numbers less than a non-negative number, n. 题解:这道题如果对每个小于n的数都进行判断是否为素数并计数会超时,因此采用筛法来解这题.建一个数组,从2开始, 把其倍数小于N的都删掉. class Solution { public: int countPrimes(int n) { vector<int>arr(n,1); int s

[LeetCode]Count Primes

题目:Count Primes 统计1-n的素数的个数. 思路1: 通常的思想就是遍历(0,n)范围内的所有数,对每个数i再遍历(0,sqrt(i)),每个除一遍来判断是否为素数,这样时间复杂度为O(n*sqrt(n)). 具体实现不在贴代码,过程很简单,两重循环就可以解决.但是效率很差,n较大时甚至会花几分钟才能跑完. 思路2: 用埃拉特斯特尼筛法的方法来求素数,时间复杂度可以达到O(nloglogn). 首先开一个大小为n的数组prime[],从2开始循环,找到一个质数后开始筛选出所有非素数

【数学】Count Primes

题目:leetcode Count Primes Description: Count the number of prime numbers less than a non-negative number, n 分析: 求出比n小的素数的个数,这个问题可以用排除法做,参考http://www.cnblogs.com/grandyang/p/4462810.html int countPrimes(int n) { if(n<=2) return 0; int res=0; int size=s

LeetCode 第 3 题(Longest Substring Without Repeating Characters)

LeetCode 第 3 题(Longest Substring Without Repeating Characters) Given a string, find the length of the longest substring without repeating characters. Examples: Given "abcabcbb", the answer is "abc", which the length is 3. Given "b