zoukankan      html  css  js  c++  java
  • Count Primes -- LeetCodes (primality test)

    Description:

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

    思路:这题第一种思路是写一个is_prime函数,来对每一个数验证一次是否是prime。

    这个方法在这个题里表现不快,但也是一个学习is_prime函数的机会。

    首先,验证一个数是不是prime,只需要用小于它的所有正整数全除一遍看是否能整除就行。实际上,我们只需要试验到sqrt(n),不需要到n-1。因为假如p * q = n的话,p和q是关于sqrt(n)对称的。

    再然后,所有数都可以表示成6 * k + i的形式,其中k为整数,i = -1, 0, 1, 2, 3, 4。当i = 0, 2, 4时该数一定是偶数,不可能是prime。当i = 3时,这个数能被3整除,也不是。因此,若一个数是prime,除了2和3,它一定能被表示成 6 * k +/- 1的形式。

    由此,我们获得了一个检测n是否是prime的思路:先验证n能否被2或者3整除。然后验证n能否被不大于sqrt(n)的所有能表示成6 * k +/- 1形式的数整除。

     1 bool is_prime(int n)
     2 {
     3     if (n <= 1) return false;
     4     else if (n <= 3) return true;
     5     else if (n % 2 == 0 || n % 3 == 0)
     6         return false;
     7     for (int i = 5; i * i <= n; i += 6)
     8         if (n % i == 0 || n % (i + 2) == 0)
     9             return false;
    10     return true;
    11 }

    接下来介绍这个题里能用到的解法。

    思路是我们先使用一个大小为n的数组,然后从2开始,将所有2的倍数全部标记成非prime。然后是3,将所有3的倍数全部标记成非prime。这里要注意的是,因为2 * 3已经在2的倍数那一步标注过了,因此这里从3的3倍开始。到4的时候,因为4已经被标注为非prime了,因此直接跳过。以此类推,将所有i从i倍开始的所有倍数标注为非prime。这个过程一直持续到i等于sqrt(n)。

     1 class Solution {
     2 public:
     3     int countPrimes(int n) {
     4         vector<bool> tab(n, true);
     5         for (int i = 2; i * i < n; i++)
     6             if (tab[i])
     7                 for (int j = i; i * j < n; j++)
     8                     tab[i * j] = false;
     9         int res = 0;
    10         for (int i = 2; i < n; i++)
    11             if (tab[i]) res++;
    12         return res;
    13     }
    14 };
  • 相关阅读:
    Java运行环境(win10)
    maven封装jar包遇到的问题
    eclipse安装STS遇到的问题
    Redis IO多路复用的理解
    操作系统文章推荐
    jdk1.8新特性
    Maven笔记
    博主推荐
    MySQL文章推荐
    多线程文章推荐
  • 原文地址:https://www.cnblogs.com/fenshen371/p/5156494.html
Copyright © 2011-2022 走看看