204.Count Primes
给定一个正整数,求小于这个数的质数个数。
Input: 10
Output: 4
Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7.
思路:
一、暴力,利用for循环,对 2~n的数遍历,当遇到质数时,将其加入动态数组中,内一次对动态数组的质数求模,若这个数是质数,则加入动态数组。第一次提交,显示超时,后来用开方,每一次只遍历到这个数的开方,然后AC,但时间复杂度还是太高了。
int countprimes(int n) { vector<int> ans; int flag = 0; for (int i = 2; i < n; i++) { int sqnum = sqrt(i); flag = 0; for (int j = 0; j < ans.size() && ans[j] <= sqnum; j++) { if (i % ans[j] == 0) { flag = 1; break; } } if (flag == 0) ans.push_back(i); } return ans.size(); }
二、利用空间换时间,将 长度为 n的数组,保存其属性,对所有2的倍数,3的倍数,5的倍数,7的倍数(当前已知质数的倍数)……写入到数组中。
int countprimes(int n) { vector<bool> prime(n, true); int ans = 0; for (int i = 2; i < n; i++) { if (!prime[i]) continue; ans += 1; for (int j = 2; i * j < n ; j++) { prime[i * j] = false; } } return ans; }
Java 版:
• 使用标记法,对于每一个素数,统计个数;
• 且以这个素数为起点,步幅长度为素数,将后面的数字,标记为非素数。
class Solution { public int countPrimes(int n) { if(n <= 2) return 0; boolean[] nums = new boolean[n]; Arrays.fill(nums, true); //一开始全部标记为 true int count = 0; for(int i = 2; i < n; i++){ if(nums[i] == true){ //对素数,开始标记 count++; for(int j = i; j < n; j += i){ nums[j] = false; //标记为非素数 } } } return count; } }