作者: 负雪明烛
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:

Input: 10
Output: 4
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都会效率低,最后用数组好了。

/**
* 统计质数的数目。使用数组,用列表效率低。
*
* @param n
* @return
*/
public static int countPrimes3(int n) { //n个元素的数组,其实只用到了n-2个。多见了2个防止输入0的时候崩溃。
int[] nums = new int[n];
//把所有的小于n的大于2的数字加入数组里
for (int i = 2; i < n; i++) {
//注意计算质数从2开始的,而数组从0开始
nums[i - 2] = i;
}
//统一的长度,优化计算
int size = nums.length;
//各种优化效率,只计算到sqrt(n)
for (int i = 0; i * i < size; i++) {
//获取数组中的数字
int temp = nums[i];
//如果不是0,则进行计算,否则直接跳过,因为这个数已经是之前的某数字的倍数
if (temp != 0) {
//把该数字的倍数都删去,因为他们都不是质数
//int i1 = temp - 1 优化效率,是因为比如用5来删除数字的时候15=3*5已经被删除过了,所以从20=5*4开始删除
for (int i1 = temp - 1; i + temp * i1 < size; i1++) {
//如果这个数不是素数则被置0,置成其他的负数也一样,只是为了区分和统计
//i + temp * i1,i是因为从当前数字开始,比如10是从5的位置开始计算位置
nums[i + temp * i1] = 0;
}
}
}
return countNums(nums);
} /**
* 计算数组中的0出现了多少次
*
* @param nums
* @return
*/
public static int countNums(int[] nums) {
int size = nums.length;
int zeros = 0;
for (int num : nums) {
if (num == 0) {
zeros++;
}
} return size - zeros;
}

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

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

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

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

class Solution(object):
def countPrimes(self, n):
"""
:type n: int
:rtype: int
"""
nums = [True] * n
for i in xrange(2, n):
j = 2
while i * j < n:
nums[i * j] = False
j += 1
res = 0
for i in xrange(2, n):
if nums[i]:
res += 1
return res

C++版本如下:

class Solution {
public:
int countPrimes(int n) {
vector<bool> nums(n, true);
for (int i = 2; i < n; i++) {
int j = 2;
while (i * j < n) {
nums[i * j] = false;
j ++;
}
}
int res = 0;
for (int i = 2; i < n; i++) {
if (nums[i]){
res ++;
}
}
return res;
}
};

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

class Solution {
public:
int countPrimes(int n) {
if (n <= 0) return false;
bool nums[n];
memset(nums, true, sizeof(nums));
for (int i = 2; i < n; i++) {
int j = 2;
while (i * j < n) {
nums[i * j] = false;
j ++;
}
}
int res = 0;
for (int i = 2; i < n; i++) {
if (nums[i]){
res ++;
}
}
return res;
}
};

参考资料

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. R语言与医学统计图形-【32】海盗图、词云图、日历图

    1.海盗图 参数众多,其语法与基础包类似. 基础图. #devtools::install_github('ndphillips/yarrr') #install.packages('yarrr') ...

  2. 类成员函数调用delete this会发生什么呢?

    有如下代码 class myClass { public: myClass(){}; ~myClass(){}; void foo() { delete this; } }; int main() { ...

  3. 宏GENERATED_BODY做了什么?

    Version:4.26.2 UE4 C++工程名:MyProject \ 一般语境下,我们说c++源码的编译大体分为:预处理.编译.链接; cppreference-translation_phas ...

  4. 分布式事务(3)---强一致性分布式事务Atomikos实战

    分布式事务(1)-理论基础 分布式事务(2)---强一致性分布式事务解决方案 分布式事务(4)---最终一致性方案之TCC 前面介绍强一致性分布式解决方案,这里用Atomikos框架写一个实战的dem ...

  5. 1 — 第一个springboot

    1.什么是springboot? 老规矩:百度百科一下 2.对springboot快速上手 1).第一种方式:通过官网来创建springboot项目 ---- 了解即可 这里面的创建方式不做过多说明, ...

  6. 这份github上被14万人点赞的Java教程太强了

    前几天有个小伙伴加我之后问了下面的这个问题.我看到后是一脸懵逼的状态,jcombobox?实话说,我已经完全忘了在Java中还有这么个东西. 在网上一番搜索后,才发现原来它是 swing 中的下拉列表 ...

  7. celery开启worker报错django.core.exceptions.ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE o

    其实挺简单的问题,但花了自己一个下午来解决,先是浏览各种博客,无果:没办法,然后去看celery官方文档,无果,近乎绝望,最后仔细看代码,找到问题所在(如下),自学狗这效率...... 下面是自己ta ...

  8. Linux之sftp服务

    Linux之sftp服务 一.sftp介绍转自:[1]Linux如何开启SFTP https://www.cnblogs.com/xuliangxing/p/7120205.htmlSFTP是Secu ...

  9. Git上项目代码拉到本地方法

    1.先在本地打开workspace文件夹,或者自定义的文件夹,用来保存项目代码的地方. 2.然后登陆GitHub账号,点击复制项目路径 3.在刚才文件夹下空白处点击鼠标右键,打开Git窗口 4.在以下 ...

  10. spring注解事务管理

    使用步骤: 步骤一.在spring配置文件中引入<tx:>命名空间<beans xmlns="http://www.springframework.org/schema/b ...