204.Count Primes

给定一个正整数,求小于这个数的质数个数。
Input: 10
Output: 4
Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7.

思路:
一、暴力,利用for循环,对 2~n的数遍历,当遇到质数时,将其加入动态数组中,内一次对动态数组的质数求模,若这个数是质数,则加入动态数组。第一次提交,显示超时,后来用开方,每一次只遍历到这个数的开方,然后AC,但时间复杂度还是太高了。

int countprimes(int n) {
    vector<int> ans;
    int flag = 0;
    for (int i = 2; i < n; i++) {
        int sqnum = sqrt(i);
        flag = 0;
        for (int j = 0; j < ans.size() && ans[j] <= sqnum; j++) {
            if (i % ans[j] == 0) {
                flag = 1;
                break;
            }
        }
        if (flag == 0) ans.push_back(i);
    }
    return ans.size();
}

 二、利用空间换时间,将 长度为 n的数组,保存其属性,对所有2的倍数,3的倍数,5的倍数,7的倍数(当前已知质数的倍数)……写入到数组中。

int countprimes(int n) {
    vector<bool> prime(n, true);
    int ans = 0;
    for (int i = 2; i < n; i++) {
        if (!prime[i]) continue;
        ans += 1;
        for (int j = 2; i * j < n ; j++) {
            prime[i * j] = false;
        }
    }
    return ans;
}

 

 

Java 版:

  • 使用标记法,对于每一个素数,统计个数;
  • 且以这个素数为起点,步幅长度为素数,将后面的数字,标记为非素数。

class Solution {
    public int countPrimes(int n) {
        if(n <= 2) return 0;
        boolean[] nums = new boolean[n];
        Arrays.fill(nums, true); //一开始全部标记为 true
        int count = 0;
        for(int i = 2; i < n; i++){
            if(nums[i] == true){ //对素数,开始标记
                count++;
                for(int j = i; j < n; j += i){
                    nums[j] = false; //标记为非素数
                }
            }       
        }
        return count;
    }
}

 

posted @ 2020-05-11 16:58  星海寻梦233  阅读(133)  评论(0编辑  收藏  举报