<LeetCode OJ> 204. Count Primes

Description:html

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



分析:

思路首先:一个数不是合数就是素数,合数更好推断呢!面试


合数:不论什么一个合数都可以表现为适当个素数的乘积的形式,
因此咱们仅仅用小于sqrt(number)的素数去除要推断的数就能够,
因为合数在sqrt(number)之内必定有素数的质因子
比方要推断100之内的素数,仅仅需推断合数就能够。仅仅用10之内的2,3。5。7就够了,10000之内的数用100之内的素数推断足以。执行时间O(N)
less

class Solution {
public:
    
    int countPrimes(int n) {
        if(n<=2)
            return 0;
        
        basenum.reserve(10001);//预留空间
        basenum.push_back(2);
       
        int cnt=1;
        for (int  number=3; number < n; number++)//计算出n之内的素数个数
        {
            int flag = true;
            int tmp = static_cast<int>(sqrt(number));
            //推断是不是素数
            int j = 0;
            while (basenum[j] <= tmp)
            {
                if (number % basenum[j] == 0)
                { //此时合数
                    flag = false; 
                    break; 
                }
                j++;
            }
            if (flag)
            { 
                basenum.push_back(number);
                cnt++;
            }
        }
        return cnt;
    }
private:
    vector<int> basenum;//用于存储素数
};


这个问题是上海交通大学2008年的研究生面试题:spa

Prime Number.net

题目描写叙述:

Output the k-th prime number.code

输入:

k≤10000htm

输出:

The k-th prime number.blog

例子输入:
3
7
例子输出:
5
17
个人答案:

#include "vector"  
#include <iostream>  
#include "fstream"
#include "algorithm"  
#include <stdio.h>
#include "string"
#include <cmath>
#include <cstdlib>
#include "map"
 
using namespace std;
 
vector<int> basenum;//用于存储素数
//素数推断法:不论什么一个合数都可以表现为适当个素数的乘积的形式,
//因此咱们仅仅用小于sqrt(number)的素数去除要推断的数number就能够,
//比方要推断100之内的素数。仅仅用10之内的2,3,5,7就够了,10000之内的数用100之内的素数推断足以。
 
void initPrime()
{
    basenum.reserve(10001);//预留空间
    basenum.push_back(2);
    basenum.push_back(3);
    basenum.push_back(5);
    basenum.push_back(7);//先压入4个素数
    int  number=11;
     
    for (int i = 5; i <= 10000; number++)//计算出10000个素数
    {
        int flag = true;
        int tmp = static_cast<int>(sqrt(number));
        //推断是不是素数
        int j = 0;
        while (basenum[j] <= tmp)
        {
            if (number % basenum[j] == 0)
            { //此时合数
                flag = false; 
                break; 
            }
            j++;
        }
        if (flag)
        { 
            basenum.push_back(number);
            i++;
        }
    }
}
 
int main()
{
    int n;
    initPrime();
    while (cin>>n)
        printf("%d\n", basenum[n - 1]);
    return 0;
}
/**************************************************************
    Problem: 1040
    User: EbowTang
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1536 kb
****************************************************************/



之前写过的最糟糕的素数推断方法:ip

//思路首先:
//最朴素(糟糕)的方法
class Solution {
public:
    bool IsPrimeNum(int num)
    {
        if (num <= 1)
            return false;
        for (int i = 2; i <= num/2; i++)
        {
            if (num % i == 0)//一旦可以整除马上返回他不是素数  
                return false;
        }
        return true;
    }
    int countPrimes(int n) {
        int cnt=0;
        int curNum=1;
        while(curNum<=n)
        {
            if(IsPrimeNum(curNum))
                cnt++;
            curNum++;
        }
        return cnt;
    }
};


小结:遇到存在对立角度的问题,可以考虑用还有一面来破解,而不拘泥于正面破解。

之后素数问题都直接推断合数问题就能够。


注:本博文为EbowTang原创,兴许可能继续更新本文。

假设转载,请务必复制本条信息!

原文地址:http://blog.csdn.net/ebowtang/article/details/50469592

原做者博客:http://blog.csdn.net/ebowtang

相关文章
相关标签/搜索