LeetCode 第 204 题 (Count Primes)
2016-07-01 12:37
501 查看
LeetCode 第 204 题 (Count Primes)
Description:
Count the number of prime numbers less than a non-negative number, n.
计算小于 N 的素数的个数。这道题目比较简单。但是想提高计算效率与需要费点脑筋。
判断一个数字 是不是素数的简单方法是 用 去除 ,如果都不能整除就说明这个数是素数。
按照这个思路可以写个简单的函数。
bool isPrime(int n) { if(n < 1) return false; for (int i = 2; i < n; i++) { if (num % i == 0) { return false; } } return true; }
这个代码还可以优化一点。不用除到 ,只要除到 就可以了。
bool isPrime(int n) { if(n < 1) return false; for (int i = 2; i * i < n; i++) { if (num % i == 0) { return false; } } return true; }
这个代码每次判断时都要算一遍 ,而第 69 题给出了一个计算 的快速算法,利用这个算法还可以再优化一点。
int mySqrt(int x) { if(x <= 0) return 0; int a1 = 1; int a2 = 46341 * 2 - 1; unsigned int a, y; if(a2 > x / 2) a2 = x; do { a = (a1 + a2) / 2; y = a * a; if(y == x) return a; if(y > x) { a2 = a; } else { a1 = a; } }while(a1 + 1 < a2); a = (a1 + a2) / 2; return a; } bool isPrime(int n) { if(n < 1) return false; int sn = mySqrt(n); for (int i = 2; i <= sn; i++) { if (num % i == 0) { return false; } } return true; }
之后计算素数个数的代码就可以写成这样。
int countPrimes(int n) { int count = 0; for (int i = 1; i < n; i++) { if (isPrime(i)) count++; } return count; }
即使写成这样,这个代码的计算复杂度还是有点大,isPrime 函数的时间复杂度是 ,countPrimes 函数的时间复杂度是 ,所以整体的复杂度是 。
实际上有一种简单的算法,时间复杂度可以降低到 。这种方法就是所谓的 Eratosthenes 筛选法(Sieve of Eratosthenes)。首先建立一张有 个元素的大表,表中每个元素都标记为 。那么这个表中 是第一个素数, 的倍数都不是素数,那么把表中 的倍数都标记为 。之后找表中在 后面第一个元素值为 的元素,这个元素就是第二个素数,当然这个数是 ,然后再将表中 的倍数全部标记为 。重复这个过程,就可以将表中所有的素数找出来了。按照这个思路写的代码如下:
int countPrimes(int n) { bool *primeTable = new bool ; for (int i = 0; i < n; i++) { primeTable[i] = true; } int i = 2; int count = 0; while (i * i < n) { if (primeTable[i]) { count++; for (int j = i * i; j < n; j += i) { primeTable[j] = false; } } i++; } while (i < n) { if(primeTable[i]) { count++; } i++; } delete[] primeTable; return count; }
除此之外,还有更快的判段一个数是否是素数的方法,时间复杂度为 。不过那种算法属于概率算法,有一定的小概率出错,以后有时间单独写一篇博客介绍那些方法。
相关文章推荐
- LeetCode 第 204 题 (Count Primes)
- 数据结构与算法简记:快速排序
- day_05双层装饰器原理_字符串格式化
- RocketMQ(四)特性
- 24种设计模式——门面模式
- 通信黑科技:NB-IoT
- PowerDesigner V16.5 安装文件 及 破解文件
- 什么是MIME?
- 如何下载谷歌地球高程为SHP格式的等高线
- Problem S
- 2014年基于Raspberry Pi的5大项目
- 2014年基于Raspberry Pi的5大项目
- hihoCode题目2
- TCP/IP TIME_WAIT状态原理
- Python字符编码判断方法分析
- 别再TM跟我说找不到满意的工作!
- xcode 菜单详解
- Gradle 实现编译和运行Java程序
- 688B: Lovely Palindromes
- 51NOD 1417 天堂里的游戏(列等式 解方程)