Note: Prime numbers start from 2, 2, 3 ...
Improvement process:
The general idea is to isprime each number less than n, isprime (int x) function for (int i = 2; I <= x/2; ++i), if X%i==0,return false.
Second, the range of isprime (int x) I is changed to I * I <= x. Without I <= sqrt (x), because sqrt time-consuming.
Third, the IsPrime is 2, 3, 5 times times the number of direct return, do not enter for loop.
Four, for each number P,P2, P2+p, p2+2p ... Are not prime, a bit like the idea of dynamic planning. At this point, instead of isprime (int x) function, but maintain a isprime[n] bool array, first set all the values are true, and then I start from 3 loop (corresponding to if the input n<3, directly return 0). Because the values in the IsPrime array after i2 are changed to False, I loop to I * I < n.
About if (!isprime[i]) continue; This sentence explains. If isprime[i] = = False, then that means it is marked in the previous I loop. Before the number of cycles is p, then I = p2 + NP, if there is no continue this sentence, then j = i * I, set J is also equal to P2 + MP, so get the equation (P2 + np) 2 = p2 + MP, solution to M = P ((p + N) 2-1), also It is said that J has been marked before the P cycle, so it can be continue directly and save time. Here is the code and the best code given in the topic tip.
1 Public intCountPrimes (intN) {2boolean[] IsPrime =NewBoolean[n];3 for(inti =2; I < n; i++) {4Isprime[i] =true;5 }6 //Loop ' s ending condition is I * I < n instead of I < sqrt (n)7 //To avoid repeatedly calling an expensive function sqrt ().8 for(inti =2; I * i < n; i++) {9 if(!isprime[i])Continue;Ten for(intj = i * I; J < N; J + =i) { OneISPRIME[J] =false; A } - } - intCount =0; the for(inti =2; I < n; i++) { - if(Isprime[i]) count++; - } - returncount; +}
Five, in the final calculation of CNT, from 2 onwards to N-1 are judged once, but the even number is definitely not a prime, so it is not necessary to access its value in the array isprime.
Since you can skip even numbers when you calculate CNT, you can also skip even numbers in the for loop of the previous Mark IsPrime, with the corresponding J + = 2 * I, because P (p + 1) must be an even number.
So the for loop becomes i + = 2, J + = 2 * I, i + = 2 (previous step is ++i, j + = I, ++i).
The final version of the code
1 classSolution {2 Public:3 intCountPrimes (intN) {4 if(N <3)return 0;5 BOOL* IsPrime =New BOOL[n];6 for(inti =3; I < n; ++i)7Isprime[i] =true;8 9 for(inti =3; I * I <= N; i + =2){Ten if(!isprime[i])Continue; One for(intj = i * I; J < N; J + =2*i) AISPRIME[J] =false; - } - the intCNT =1; -cout<<isprime[9]<<Endl; - for(inti =3; I < n; i + =2){ - if(Isprime[i]) + +CNT; + } - returnCNT; + } A};
Leetcode 204. Count Primes