线性筛子

//暴力枚举;
int isPrime(int n)
{
	if(n<=1)return 0;
	for(int i=2;i*i<=n;i++)
	if(n%i==0)return 0;
	return 1;
	//每个数我们需要枚举sqrt(n)次,有n个数需要o(nsqrt(n));
}

//埃拉托斯特尼筛


	memset(falg,0,sizeof(flag));
	int tot=0;
	for(int i=2;i<=n;i++)
	{
		if(!flag[i])
		prime[++tot]=i;
		for(int j=2*i;j<=n;j+=i)flag[j]=1;
	|
	//时间复杂度∑(n/i)=n*∑(1/i)就算从2枚举到n复杂度是调和的,但是现在只需要枚举质数,所以复杂度是nloglogn     所以复杂度是o(nlog(logn));

//上面的算法有些数被多个质因子访问,如15被3和5访问进行flag操作;
//算法改进后可以只被最小质因子访问;
//欧拉筛法
memset(flag,0,sizeof(flag));
int tot=0;
for(int i=2;i<=n;i++)
{
	if(!flag[i])prime[++tot]=1;
	for(int j=1;j<=tot&&i*prime[j]<=n;j++)
	flag[i*prime[j]]=1;
	if(i%prime[j]==0)break;//如果prime[j]能整除i,说明i*prime[j]已经找到最小质因子了,剩下的质														             //                                                          因子没必要找了; 举个例子
															//12是被2筛掉的因为6*2=12,在判断6%2==0的时候已经知道12能被2这个质因子整除了还能被prime[i]*prime[i]整除
															//我们可以想象如果i%prime[j]==0成立,那么i一定是一个合数(有因子),那么我们一定可以把i分解成a*b,
并且ab中 有一个数一定是素数.则有i*prime[j]=a*b*prime[j],我们假设a是i*prime[j]的最小素因子,
那么我们 遍历到b*prime[j]时一定能把i*prime[j]标记成合数,此时a是i*prime[j]的最小素数,所以在
遇到i的 时候我们直接跳出即可.复杂度是o(n);
}

你可能感兴趣的:(leetcode)