LeetCode 204. Count Primes

 

注:质数从2开始,2、3……

 

改进过程:

一、常规思路是对小于n的每一个数进行isPrime判断,isPrime(int x)函数中for(int i = 2; i <= x /2; ++i),如果x%i==0,return false。

二、将isPrime(int x)中i的范围改为i * i <= x。不用i <= sqrt(x),因为sqrt耗时。

三、isPrime中把是2、3、5倍数的数直接return,不进入for循环。

四、对于每一个数p,p2、p2+p、p2+2p……均不为素数,有点像动态规划的思想。此时可以不用isPrime(int x)函数,而是维护一个isPrime[n]的bool数组,先设里面所有的值均为true,然后i从3开始循环(对应的是如果输入n<3,直接return 0)。因为会把i2之后的一系列数在isPrime数组中的值变为false,因此i循环至i * i < n。

关于if(!isPrime[i]) continue;这一句解释一下。如果isPrime[i] == false,那么也就是说在之前的i循环里被标记过了。设之前的循环的数为p,那么 i = p+ np,如果没有continue这一句的话,那么 j = i * i,设j也等于p2 + mp,于是得到等式 (p+ np)2 = p+ mp,解得m = p((p + n)2 - 1),也就是说j之前在p循环时已经被标记过了,因此可以直接continue,节省时间。以下是代码,也是题目提示中给出的最优代码。

 1 public int countPrimes(int n) {
 2    boolean[] isPrime = new boolean[n];
 3    for (int i = 2; i < n; i++) {
 4       isPrime[i] = true;
 5    }
 6    // Loop's ending condition is i * i < n instead of i < sqrt(n)
 7    // to avoid repeatedly calling an expensive function sqrt().
 8    for (int i = 2; i * i < n; i++) {
 9       if (!isPrime[i]) continue;
10       for (int j = i * i; j < n; j += i) {
11          isPrime[j] = false;
12       }
13    }
14    int count = 0;
15    for (int i = 2; i < n; i++) {
16       if (isPrime[i]) count++;
17    }
18    return count;
19 }

五、在最后计算cnt时,从2开始到n-1都被判断了一遍,但是偶数绝对不是素数,因此是没必要访问其在数组isPrime中的值的。

既然计算cnt时可以跳过偶数,那么在之前的标记isPrime的for循环里,也可以跳过偶数,相应的j每次+= 2 * i,因为p(p + 1)必定为偶数。

所以for循环里依次变为i += 2, j += 2 * i, i += 2(上一步为++i, j += i, ++i)。

 

最终版代码

 1 class Solution {
 2 public:
 3     int countPrimes(int n) {
 4         if(n < 3) return 0;
 5         bool* isPrime = new bool [n];
 6         for(int i = 3; i < n; ++i)
 7             isPrime[i] = true;
 8             
 9         for(int i = 3; i * i <= n; i += 2){
10             if(!isPrime[i]) continue;
11             for(int j = i * i; j < n; j += 2 * i)
12                 isPrime[j] = false;
13         }
14         
15         int cnt = 1;
16         cout<<isPrime[9]<<endl;
17         for(int i = 3; i < n; i += 2){
18             if(isPrime[i]) ++cnt;
19         }
20         return cnt;
21     }
22 };

 

转载于:https://www.cnblogs.com/co0oder/p/5286781.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/418780.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

base64的用法

js base64的用法&#xff1a;https://www.jianshu.com/p/14437764eff3 java base64的用法&#xff1a; String nameBase64 escOrgVo.getName();String name "";if (StringUtils.isNotBlank(nameBase64)) {try {name new String(Base64.decode(nameBase64), &quo…

75-商品服务-品牌分类关联与级联更新

1.注意事务的使用&#xff08;这里事务在controller里面加&#xff09; 2.认识到更新某一表中的某个属性的时候要同步更新冗余表里面的相同信息。

SQL SERVER-约束

NOT NULL - 指示某列不能存储 NULL 值。UNIQUE - 保证某列的每行必须有唯一的值。PRIMARY KEY - NOT NULL 和 UNIQUE 的结合。确保某列&#xff08;或两个列多个列的结合&#xff09;有唯一标识&#xff0c;有助于更容易更快速地找到表中的一个特定的记录。FOREIGN KEY - 保证一…

78--规格参数的查询与修改功能

1.枚举类的应用&#xff1a;这样如果在表中修改了&#xff0c;就不用到处去代码中修改了

HTTP POST GET 本质区别详解(转)

一 原理区别 一般在浏览器中输入网址访问资源都是通过GET方式&#xff1b;在FORM提交中&#xff0c;可以通过Method指定提交方式为GET或者POST&#xff0c;默认为GET提交 Http定义了与服务器交互的不同方法&#xff0c;最基本的方法有4种&#xff0c;分别是GET&#xff0c;POST…

java 8 list和数组之间的相互转换

list转数组&#xff1a;https://blog.csdn.net/qq_37653556/article/details/83271784 https://blog.csdn.net/qq_39985330/article/details/95332949

80--查询分组关联属性

1.mybatis-plus for-each标签的使用 2.PostMapping 要用注解 RequestBody 进行封装数据

配置Log4j(很详细)

Log4J的配置文件(Configuration File)就是用来设置记录器的级别、存放器和布局的&#xff0c;它可接keyvalue格式的设置或xml格式的设置信息。通过配置&#xff0c;可以创建出Log4J的运行环境。1. 配置文件Log4J配置文件的基本格式如下&#xff1a; #配置根Loggerlog4j.rootLog…

P91--商品保存debug完成

1.坑&#xff1a;springcloud之Feign超时问题(Read timed out executing POST http://***) 解决方案 首先&#xff0c;我们看下Feign的简介 Feign 是一个声明式的web服务客户端&#xff0c;这便得编写web服务客户端更容易&#xff0c;使用Feign 创建一个接口并对它进行注解&am…

swagger2 分组

https://blog.csdn.net/stonexmx/article/details/77604571 自定义注解 package com.awj.mall.restfulapi.common.swagger.annotion;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import …

P93

1.把返回的时间数据格式化 spring 内置的jackson

解析stm32的时钟

STM32 时钟系统 http://blog.chinaunix.net/uid-24219701-id-4081961.html STM32的时钟系统 *** http://www.cnblogs.com/wangh0802PositiveANDupward/archive/2012/12/24/2831535.html 高速时钟提供给芯片主体的主时钟.低速时钟只是提供给芯片中的RTC&#xff08;实时时…

java 接口式自定义回调函数

定义接口 package com.zjxnjz.mall.admin.test;public interface CallBack {void handler(String message);}测试 package com.zjxnjz.mall.admin.test;public class TestCallBack {public static void setHello(CallBack callback) {int count0;while(count<100) {count;…

前端学习(1841):前端面试题之react和vue区别

相同点 都有组件化开发和Virtual DOM都支持props进行父子组件间数据通信都支持数据驱动视图, 不直接操作真实DOM, 更新状态数据界面就自动更新都支持服务器端渲染都有支持native的方案,React的React Native,Vue的Weex 不同点 数据绑定: vue实现了数据的双向绑定,react数据流动是…

94--SKU检索

1.SKU就是指每种商品&#xff0c;各种参数不同的就是一种 2.为什么用and,因为这个and用括号把or条件括起来 3.ge大于 le 小于 4.打印日志 这个包下的所有debug都调成debug

redis 缓存 key常量命名规则

package com.awj.mall.restfulapi.common.consts;public class CacheConsts {// 短信验证码类型/*** 登录*/public static final String SMS_TYPE_LOGIN "cache:api:sms_login_";/*** 重置密码*/public static final String SMS_TYPE_RESETPWD "cache:api:sms…