統計所有小於非負整數 n 的質數的數量。
示例:
輸入: 10 輸出: 4 解釋: 小於 10 的質數一共有 4 個, 它們是 2, 3, 5, 7 。
題解:
version1:
- 檢驗一個數n是否是質數,只要將n對2到n-1判斷取餘是否爲0即可
- 根據定理 2到n-1判斷取餘可縮小至2到 根號(n-1)之間
- 又 2到根號(n-1)之間可以表示:2到n-1之間的質數
- 可以優化爲:n對(根號(n-1)之間的質數)判斷取餘是否爲0
class Solution {
public int countPrimes(int n) {
if(n<=2){
return 0;
}
List<Integer> list = new ArrayList<>();//保存當前已確定的質數
list.add(2);
/*
檢驗一個數n是否是質數,只要將n對2到n-1判斷取餘是否爲0即可
根據定理 2到n-1判斷取餘可縮小至2到 根號(n-1)之間
又 2到根號(n-1)之間可以表示:2到n-1之間的質數
可以優化爲:n對(根號(n-1)之間的質數)判斷取餘是否爲0
*/
for(int i=3 ; i<n ; i++){
int len = list.size();
boolean isPrime = true;
for(int j=0 ; j<len && (list.get(j)<=Math.sqrt(i)) ; j++){
if(i%list.get(j)==0){
isPrime = false;
break;
}
}
if(isPrime){
list.add(i);
}
}
return list.size();
}
}
version2:
參考題解中解答:改除爲乘:每出現一個質數,將所有它的倍數全部標記,移除待比較序列
class Solution {
public int countPrimes(int n) {
if(n<=2){
return 0;
}
int[] nums = new int[n];
int ret = 0;
for(int i=2 ; i<n ; i++){
if(nums[i] == -1){
continue;
}
ret++;
//這裏得用倍乘,不能挨個遍歷,在i較大時候複雜度會大大降低
for(int j=2 ; i*j<n ; j++){
nums[i*j] = -1;//標記爲非質數
}
}
return ret;
}
}