作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


[LeetCode]

题目地址:https://leetcode.com/problems/count-primes/

Total Accepted: 36655 Total Submissions: 172606 Difficulty: Easy

题目描述

Count the number of prime numbers less than a non-negative number, n.

Example:

  1. Input: 10
  2. Output: 4
  3. Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7.

题目大意

计算小于n的素数有多少个。

解题方法

素数筛法

http://blog.csdn.net/blitzskies/article/details/45442923 提示用Sieve of Eratosthenes的方法。

素数筛法就是把这个数的所有倍数都删除掉,因为这些数一定不是素数。最后统计一下数字剩余的没有被删除的个数就好。

也是学习了。

Java解法。

重点是优化效率,每一步的效率都要优化。

用List都会效率低,最后用数组好了。

  1. /**
  2. * 统计质数的数目。使用数组,用列表效率低。
  3. *
  4. * @param n
  5. * @return
  6. */
  7. public static int countPrimes3(int n) {
  8. //n个元素的数组,其实只用到了n-2个。多见了2个防止输入0的时候崩溃。
  9. int[] nums = new int[n];
  10. //把所有的小于n的大于2的数字加入数组里
  11. for (int i = 2; i < n; i++) {
  12. //注意计算质数从2开始的,而数组从0开始
  13. nums[i - 2] = i;
  14. }
  15. //统一的长度,优化计算
  16. int size = nums.length;
  17. //各种优化效率,只计算到sqrt(n)
  18. for (int i = 0; i * i < size; i++) {
  19. //获取数组中的数字
  20. int temp = nums[i];
  21. //如果不是0,则进行计算,否则直接跳过,因为这个数已经是之前的某数字的倍数
  22. if (temp != 0) {
  23. //把该数字的倍数都删去,因为他们都不是质数
  24. //int i1 = temp - 1 优化效率,是因为比如用5来删除数字的时候15=3*5已经被删除过了,所以从20=5*4开始删除
  25. for (int i1 = temp - 1; i + temp * i1 < size; i1++) {
  26. //如果这个数不是素数则被置0,置成其他的负数也一样,只是为了区分和统计
  27. //i + temp * i1,i是因为从当前数字开始,比如10是从5的位置开始计算位置
  28. nums[i + temp * i1] = 0;
  29. }
  30. }
  31. }
  32. return countNums(nums);
  33. }
  34. /**
  35. * 计算数组中的0出现了多少次
  36. *
  37. * @param nums
  38. * @return
  39. */
  40. public static int countNums(int[] nums) {
  41. int size = nums.length;
  42. int zeros = 0;
  43. for (int num : nums) {
  44. if (num == 0) {
  45. zeros++;
  46. }
  47. }
  48. return size - zeros;
  49. }

没必要把所有的数字都保存到一个数组里面,可以直接记录和数字对应的位置的数字是不是质数。如果不是质数,则在对应位置保存true.最后统计不是true的,即质数的个数即可。

这个方法可以通用下去。类似的统计的题目只记录对应的位置是否满足条件,最后统计符合条件的个数。

  1. /**
  2. * 统计质数的数目。使用数组,用列表效率低。
  3. *
  4. * @param n
  5. * @return
  6. */
  7. public static int countPrimes4(int n) {
  8. //n个元素的数组,其实只用到了n-2个。多见了2个防止输入0的时候崩溃。
  9. boolean[] nums = new boolean[n];
  10. //各种优化效率,只计算到sqrt(n)
  11. for (int i = 2; i * i < n; i++) {
  12. //获取数组中的数字是不是为0
  13. //不是质数则为true
  14. boolean temp = nums[i];
  15. //如果不是true,说明不是质数,则进行计算,否则直接跳过,因为这个数已经是之前的某数字的倍数
  16. if (!temp) {
  17. //把该数字的倍数都删去,因为他们都不是质数
  18. //int i1 = temp - 1 优化效率,是因为比如用5来删除数字的时候15=3*5已经被删除过了,所以从20=5*4开始删除
  19. for (int j = i; i * j < n; j++) {
  20. //如果这个数不是素数则被置true
  21. //i + temp * i1,i是因为从当前数字开始,比如10是从5的位置开始计算位置
  22. nums[i * j] = true;
  23. }
  24. }
  25. }
  26. return countNums2(nums);
  27. }
  28. /**
  29. * 计算数组中的不是素数的false出现了出现了多少次
  30. *
  31. * @param nums
  32. * @return
  33. */
  34. public static int countNums2(boolean[] nums) {
  35. int notZeros = 0;
  36. for (int i = 2; i < nums.length; i++) {
  37. if (!nums[i]) {
  38. notZeros++;
  39. }
  40. }
  41. return notZeros;
  42. }

二刷,使用Python解法,速度很慢,勉强通过了。

  1. class Solution(object):
  2. def countPrimes(self, n):
  3. """
  4. :type n: int
  5. :rtype: int
  6. """
  7. nums = [True] * n
  8. for i in xrange(2, n):
  9. j = 2
  10. while i * j < n:
  11. nums[i * j] = False
  12. j += 1
  13. res = 0
  14. for i in xrange(2, n):
  15. if nums[i]:
  16. res += 1
  17. return res

C++版本如下:

  1. class Solution {
  2. public:
  3. int countPrimes(int n) {
  4. vector<bool> nums(n, true);
  5. for (int i = 2; i < n; i++) {
  6. int j = 2;
  7. while (i * j < n) {
  8. nums[i * j] = false;
  9. j ++;
  10. }
  11. }
  12. int res = 0;
  13. for (int i = 2; i < n; i++) {
  14. if (nums[i]){
  15. res ++;
  16. }
  17. }
  18. return res;
  19. }
  20. };

C++数组初始化需要使用memset,而且数组的大小n不能是0,数组解法如下。

  1. class Solution {
  2. public:
  3. int countPrimes(int n) {
  4. if (n <= 0) return false;
  5. bool nums[n];
  6. memset(nums, true, sizeof(nums));
  7. for (int i = 2; i < n; i++) {
  8. int j = 2;
  9. while (i * j < n) {
  10. nums[i * j] = false;
  11. j ++;
  12. }
  13. }
  14. int res = 0;
  15. for (int i = 2; i < n; i++) {
  16. if (nums[i]){
  17. res ++;
  18. }
  19. }
  20. return res;
  21. }
  22. };

参考资料

http://blog.csdn.net/blitzskies/article/details/45442923

https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#cite_note-horsley-1

http://blog.csdn.net/xudli/article/details/45361471

日期

2015/10/19 23:38:24
2018 年 11 月 29 日 —— 时不我待

【LeetCode】 204. Count Primes 解题报告(Python & C++)的更多相关文章

  1. [LeetCode] 204. Count Primes 解题思路

    Count the number of prime numbers less than a non-negative number, n. 问题:找出所有小于 n 的素数. 题目很简洁,但是算法实现的 ...

  2. [leetcode] 204. Count Primes 统计小于非负整数n的素数的个数

    题目大意 https://leetcode.com/problems/count-primes/description/ 204. Count Primes Count the number of p ...

  3. [LeetCode] 204. Count Primes 质数的个数

    Count the number of prime numbers less than a non-negative number, n. Example: Input: 10 Output: 4 E ...

  4. [LeetCode] 204. Count Primes 计数质数

    Description: Count the number of prime numbers less than a non-negative number, n click to show more ...

  5. Java [Leetcode 204]Count Primes

    题目描述: Description: Count the number of prime numbers less than a non-negative number, n. 解题思路: Let's ...

  6. Java for LeetCode 204 Count Primes

    Description: Count the number of prime numbers less than a non-negative number, n. 解题思路: 空间换时间,开一个空间 ...

  7. LeetCode 204. Count Primes (质数的个数)

    Description: Count the number of prime numbers less than a non-negative number, n. 题目标签:Hash Table 题 ...

  8. LeetCode 204 Count Primes

    Problem: Count the number of prime numbers less than a non-negative number, n. Summary: 判断小于某非负数n的质数 ...

  9. (easy)LeetCode 204.Count Primes

    Description: Count the number of prime numbers less than a non-negative number, n. Credits:Special t ...

随机推荐

  1. MySQL_集群

    管理节点:192.168.31.66 sql节点1+data1节点:192.168.31.42 sql节点2+data2节点:192.168.31.128 llll

  2. Excel-vlookup(查找值,区域范围,列序号,0)如何固定住列序列号,这样即使区域范围变动也不受影响

    突然,发现VLOOKUP的列序列号并不会随着区域范围的改变而自动调节改变,只是傻瓜的一个数,导致V错值.所有,就想实现随表格自动变化的列序号. 方法一:在列序号那里,用函数得出永远想要的那个列在区域范 ...

  3. mysql数据定义语言DDL

    库的管理 创建 create 语法:create database 库名 [character set 字符集] # 案例:创建库 create database if not exists book ...

  4. pow()是如何实现的?

    如1.5 ** 2.5,如何计算?似乎是这样的: 1. cmath calculates pow(a,b) by performing exp(b * log(a)). stackoverflow 2 ...

  5. c++ cmake及包管理工具conan简单入门

    cmake是一个跨平台的c/c++工程管理工具,可以通过cmake轻松管理我们的项目 conan是一个包管理工具,能够自动帮助我们下载及管理依赖,可以配合cmake使用 这是一个入门教程,想深入了解的 ...

  6. Kafka入门教程(一)

    转自:https://blog.csdn.net/yuan_xw/article/details/51210954 1 Kafka入门教程 1.1 消息队列(Message Queue) Messag ...

  7. 大数据学习day25------spark08-----1. 读取数据库的形式创建DataFrame 2. Parquet格式的数据源 3. Orc格式的数据源 4.spark_sql整合hive 5.在IDEA中编写spark程序(用来操作hive) 6. SQL风格和DSL风格以及RDD的形式计算连续登陆三天的用户

    1. 读取数据库的形式创建DataFrame DataFrameFromJDBC object DataFrameFromJDBC { def main(args: Array[String]): U ...

  8. 什么是 IP 地址 – 定义和解释

    IP 地址定义 IP 地址是一个唯一地址,用于标识互联网或本地网络上的设备.IP 代表"互联网协议",它是控制通过互联网或本地网络发送的数据格式的一组规则. 本质上,IP 地址是允 ...

  9. 容器之分类与各种测试(四)——unordered-multimap

    unordered-multiset与unordered-multimap的区别和multiset与multimap的区别基本相同,所以在定义和插入时需要注意 key-value 的类型. 例程 #i ...

  10. Linux FTP的主动模式与被动模式

    Linux FTP的主动模式与被动模式 一.FTP主被动模式        FTP是文件传输协议的简称,ftp传输协议有着众多的优点所以传输文件时使用ftp协议的软件很多,ftp协议使用的端口是21( ...