leetcode204 --- Elsieve sieve and linear sieve

Essiere sieve

We consider the fact that if xxx is a prime number, then greater thanxxx ofxxMultiples of x 2 x 2x2x, 3 x 3x 3 x ,… must not be a prime number, so we can start from here.

We are Prime [ i ] is Prime[i]i s P r im e [ i ] display numberiiIs i a prime number, if it is a prime number, it is1 11 , otherwise0 00 . Traversing each number from small to large, if the number is a prime number, mark all its multiples as composite numbers (except the prime number itself), that is,0 00 , so that we can know the number of prime numbers at the end of the run.

You can continue to optimize here, because for a prime number xxx , if we start from 2 x 2xas mentioned above2 The start mark of x is actually redundant, it should start directly fromx ⋅ xx\cdot xxx starts marking because2 x , 3 x , … 2x,3x,…2 x ,3 x ,... these numbers must have been previously marked by multiples of other numbers, such as2 2All multiples of 2 , 3 3All multiples of 3 etc.

class Solution {
    
    
public:
    int countPrimes(int n) {
    
    
        vector<int> isPrime(n,1);
        int res = 0;
        for(long long i=2;i<n;i++) {
    
    
            if(isPrime[i]) {
    
    
                ++res;
                for(long long j=i*i; j<n; j+=i) {
    
    
                    isPrime[j] = 0;
                }
            }
        }
        return res;
    }
};

Linear Sieve

The Esperanto sieve has the behavior of repeated marking. For example, 45 will be marked repeatedly by 3 and 5. The linear sieve can avoid this situation. The linear sieve is also called the Euler sieve. The Euler sieve needs to maintain a prime number table. For 2 ≤ i < n 2 \le i < n2i<n , when traversing to the integeriii , perform the following operations,

1, Ruo iii is a prime number, ieiii is not marked as a composite number, theniii join the prime number table

2. Traverse the list of prime numbers from small to large, and for each prime number prime primeprime ,当 i ∗ p r i m e < n i * prime < n iprime<When n , perform the following operations:

​ a、将 i ∗ p r i m e i*prime ip r im e is marked as a composite number

​b, Ruu iii can beprime primep r im e is divisible, then end traversing the list of prime numbers

The principle here is that if if iii can beprime primep r im e divisible, then recordprime ′ prime'prime' is greater thanprime primeThe prime number of p r im e , y = x ∗ prime ′ y=x*prime'y=xprime ,则有 y = x p r i m e ∗ p r i m e ′ ∗ p r i m e y = \frac{x}{prime} * prime' *prime y=primexprimep r im e , when traversing to $\frac{x}{prime} * prime' $,yyy will be primedprime primep r im e mark, due toprime < prime ' prime < prime'prime<p r im e ' , so whenxprime \frac{x}{prime}primexis an integer, i.e. x mod prime == 0 x \ mod \ prime == 0x mod prime==0 , this integer can beprimed ′ prime'prime' mark, soyyy will be labeled by its smallest prime factor.

Since the Euler sieve ensures that each composite number is labeled by its smallest prime factor, it ensures that each composite number is labeled only once.

class Solution {
    
    
public:
    int countPrimes(int n) {
    
    
        vector<int> isPrime(n, 1);
        vector<int> Prime;
        for (int i = 2; i < n; ++i) {
    
    
            if (isPrime[i]){
    
    
                Prime.push_back(i);
            } 
                
            for(auto j:Prime) {
    
    
                if ((long long)i * j < n) {
    
    
                    isPrime[i*j] = 0;
                } else {
    
    
                    break;
                }
                if (i % j == 0) break;
            }

        }
        return Prime.size();
    }
};

However, what appears to be fewer linear sieve operations actually takes longer to run because more operations are performed

Guess you like

Origin blog.csdn.net/weixin_43903639/article/details/129295578