1. 程式人生 > >Leetcode 204計數質數

Leetcode 204計數質數

計數質數

統計所有小於非負整數 的質數的數量。

示例:

輸入: 10

輸出: 4

解釋: 小於 10 的質數一共有 4 個, 它們是 2, 3, 5, 7 。

 

 

 

比計算少n中素數的個數。
素數又稱質數,是指僅僅能被1和它自身相除的自然數。

須要注意的是1既不是素數也不是合數。

2是最小的素數。

使用推斷一個數是否是素數的函式,那麼這個函式須要進行一輪迴圈,在給定的小於n中又要進行一輪迴圈。所以時間複雜度是O(n^2)。

能夠對推斷一個數是否是素數的函式進行優化。對於數i,能夠僅僅對2到√i之間的數進行推斷。這樣時間複雜度減少到了O(nlogn)。

可是上面的解法在leetcode中還是超時。

於是想是否存在僅僅進行一輪迴圈的方法。即在遍歷1至n-1一次的過程中記錄下素數的個數。可是後面就不知道怎麼處理。

然後看leetcode中的小提示,發現了一種更優的尋找素數的方法。首先看以下的這個圖:

 

這個圖事實上就道出了這個演算法是怎麼進行的。使用一個長度是n的hash表,最開始這個hash表中的全部元素都是沒有被處理的,從2開始遍歷,假設這個元素沒有被處理,那麼將素數的個數加1,然後將2*2,2*3,2*4……2* k( 2* k < n)標記為已經被處理了的。接著開始處理3,同理將3*2,3*3,3*4…..3*m( 3 * m < n)標記為已被處理了的,接著是4,因為這個元素已經被處理。繼續向後遍歷。這樣一直處理下去。

從這道題中又意識到了一個整數會溢位會導致問題的小技巧。

 1 import java.math.*;
 2 class Solution {
 3     public int countPrimes(int n){
 4         int[] mask=new int[n];
 5         int count=0;
 6         for(int i=2;i<n;i++){
 7             if(mask[i]==0){
 8                 count++;
 9                 for(int j=2;i*j<n;j++){
10 mask[i*j]=1; 11 } 12 } 13 } 14 return count; 15 } 16 }