LeetCode-探索-初级算法-数学-2. 计数质数(个人做题记录,不是习题讲解)
LeetCode探索-初级算法:https://leetcode-cn.com/explore/interview/card/top-interview-questions-easy/
- 计数质数
-
语言:java
-
思路:我用了双层for循环,然后就果断超时了。后面看网上的文章得知用动态规划的思想,在前面几次for循环就顺便求解了后面的情况,更加省时间。
https://blog.csdn.net/qq_38595487/article/details/80032510
-
代码(15ms):
class Solution { public int countPrimes(int n) { int count = 0; boolean disPrimses[] = new boolean[n]; for(int i = 2; i < n; ++i){ if(!disPrimses[i]){ ++count; for(int j =1; j * i < n; ++j){ disPrimses[j*i] = true; } } } return count; } }
-
参考代码(11ms):思想都差不多,都是动态规划,在之前的循环中就先计算后面的数字是否质数,这样后面for循环可以避免重复计算,浪费时间。比较亮点的地方应该就是这个内层循环的j是从i*i开始的,可以进一步减少重复计算。
class Solution { public static int countPrimes(int n) { boolean[] notPrimes = new boolean[n+1]; int count = 0; for(int i = 2; i < n; i++){ if(notPrimes[i]){ continue; } count++; for(long j = (long)i*i;j<n;j+=i){ notPrimes[(int)j] = true; } } return count; } }
-
参考后重写(12ms):
class Solution { public int countPrimes(int n) { boolean disPrimes[] = new boolean[n]; int count = 0; for(int i = 2; i < n; ++i){ if(disPrimes[i])//如果不是质数,直接下次循环 continue; ++count; for(long j = (long)i*i; j < n; j += i){//记得转换成long,不然溢出情况报错 disPrimes[(int)j] = true; } } return count; } }