题目:
Count the number of prime numbers less than a non-negative number, n
题意:
统计比n小的整数下的质数个数。
解题思路:
首先一拿到这题,LZ的思路就是很简单的采用遍历,然后依次去判断每个数是否能被2整除,如果这个数能被某个数整除,那么就说明它不是质数,而且这里对于每个数不用循环到n位置,只要到sqrt即可。这是一个小技巧。但是这种方法实现的导致超时,因为要两层循环,而且循环体里又是做除的判断,所以非常麻烦,因此在考虑用下面这个方法,这个方法是一种非常好的改进:因为在n个数时,从2开始,如果2的倍数小于n的,那么一定不是质数;同理,依次考虑3的倍数,4的倍数等等。但是这里又有一个小技巧,比如10 = 5 * 2,那么在考虑2的倍数的时候,其实已经将这个10去掉了,所以考虑5的倍数时候,这个10就不用再考虑了。所以可以考虑从i * i的倍数考虑,然后间隔为i。这样不用做除的运算,而且用了一个boolean的数组,所以如果以后要求小于n的质数的情况下,可以考虑用这种做法,这种做法比单纯的用除法去做,效率要好很多。所以非常推荐用这种。
public class Solution
{
public int countPrimes(int n)
{
boolean[] isPrime = new boolean[n];
for (int i = 2; i < n; i++)
{
isPrime[i] = true; //先用一个boolean数组来初始化,所有元素都为true
}
// Loop's ending condition is i * i < n instead of i < sqrt(n)
// to avoid repeatedly calling an expensive function sqrt().
for (int i = 2; i * i < n; i++)
{
if (!isPrime[i]) continue; //如果某个数还是false,也就是说不可能是质数,那么就跳过这次循环
for (int j = i * i; j < n; j += i) //否则就采用从这个数的平方项开始继续执行循环
{
isPrime[j] = false; //碰到这个数的倍数的,那么就变为false;
}
}
int count = 0;
for (int i = 2; i < n; i++)
{
if (isPrime[i]) count++;
}
return count;
}
}