「这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战」。
小学数学课本中我们第一次接触素数、偶数、质数、合数等,你还记得他们的定义么?给你一个正整数,如何使用算法高效判断一个数属于哪类数呢?今天我们分别有两种方法实现判断一个数的前面有多少个质数。
题目描述
统计所有小于非负整数 n 的质数的数量。
题目示例
题目解法
解法一:埃氏筛选法
先初始化一个标志位的数组,而后从2开始,将其平方小于n的值逐个标记合数
/**
* 埃氏筛选法
*/
class Solution {
public int countPrimes(int n) {
int[] isPrime = new int[n];
// 装填所有值为1,标志位
Arrays.fill(isPrime, 1);
// 统计质数个数
int ans = 0;
for (int i = 2; i < n; ++i) {
// 把未改变值的逐个更新
if (isPrime[i] == 1) {
ans += 1;
// 核心逻辑,i的平方及其+i一定不是
if ((long) i * i < n) {
for (int j = i * i; j < n; j += i) {
isPrime[j] = 0;
}
}
}
}
return ans;
}
}
解法二:线性列表筛
同埃氏筛选不同的是,使用线性列表标识合数群体
/**
* 线性列表筛
*/
class Solution {
public int countPrimes(int n) {
// 维护一个list
List<Integer> primes = new ArrayList<Integer>();
int[] isPrime = new int[n];
// 填充标识位
Arrays.fill(isPrime, 1);
for (int i = 2; i < n; ++i) {
if (isPrime[i] == 1) {
primes.add(i);
}
// 标记和数
for (int j = 0; j < primes.size() && i * primes.get(j) < n; ++j) {
isPrime[i * primes.get(j)] = 0;
if (i % primes.get(j) == 0) {
break;
}
}
}
return primes.size();
}
}
LeetCode原题链接:204. 计数质数 - 力扣(LeetCode) (leetcode-cn.com)