关于素数:面试官你知道怎么求素数吗

摘要:面试官:你晓得怎么求素数吗?我:求素数?本文分享自华为云社区《很多人不晓得的求素数的正确办法》,原文作者:bigsai 。 前言当初的面试官,是有数开发者的梦魇,可能吊打面试官的属实不多,因为大部分面试官真的有那么那几下子。但在面试中,咱们这些小生存者不能全盘否定只能单点冲破—从某个问题上让面试官眼前一亮。这不,明天就来分享来了。 这年头,算法岗内卷不说,开发岗也有点内卷,对开发者要求越来越高了,而面试官也是挖空心思的 “刁难” 面试者,但凡都喜爱由浅入深,但凡都喜爱问个:你晓得为什么?你晓得原理吗?之类。并且,以前只是大厂面试官喜爱问算法,大厂员工底子好,很多甚至有ACM教训或者零碎刷题教训,这很容易了解,但当初一些小公司面试官也是张口闭口 xx算法、xx数据结构你说说看,这不,真的被问到了。 求一个质数在这么一次的过程,面试官问我算法题我不吃惊,我实现早把十大排序原理、复杂度剖析、代码手写实现进去了,也把链表、树的各种操作复习的滚瓜烂熟,不过忽然就是很惊讶的面试官来了一道求素数问题,我把场景还原一下: 面试官:你晓得怎么求素数吗? 我:求素数? 面试官:是的,就是求素数。 我:这很简略啊,判断一个数为素数,那么必定就没有两个数(除了本身和1)相乘等于它,只须要枚举看看有没有可能被它整除的数就能够了,如果有那么就不是素数,如果没有,那么就是素数。 面试官露出一种悲观的表情,说我说的对,但没答到点子上,让我具体说一下。 上面开始开始我的表演: 首先,最笨的办法,判断n是否为素数,就是枚举[2,n-1]之间有没有间接可能被n整除的,如果有,那么返回false这个就不是素数,否则就是素数,代码如下: boolean isprime(int value){ for(int i=2;i<value;i++) { if(value%i==0) {return false;} } return true;}这种判断一个素数的工夫复杂度为O(n). 然而其实这种太浪费时间了,齐全没必要这样,能够优化一下 。如果一个数不是质数,那么必然是两个数的乘积,而这两个数通常一个大一个小,并且小的小于等于根号n,大的大于等于根号n,咱们只须要枚举小的可能范畴,看看是否可能被整除,就能够判断这个数是否为素数啦。例如100=250=425=520=1010 只须要找2—10这个区间即可。右侧的肯定有个对应的不须要管它。 boolean isprime(int value){ for(int i=2;i*i<value+1;i++) { if(value%i==0) {return false;} } return true;}这里之所以要小于value+1,就是要蕴含根号的状况,例如 3*3=9.要蕴含3.这种工夫复杂度求单个数是O(sqrt(n))。面试官我给你画张图让你看看其中区别: 说到这里面试官露出快慰的笑容。 面试官:不错不错,基本点把握了 我:老哥,其实求素数精华不在这,这个太低效在很多时候,比方求小于n的所有素数,你看看怎么搞? 面试官:用个数组用第二种办法求O(n*sqrt(n))还行啊。 求多个素数求多个素数的时候(小于n的素数),下面的办法就很繁琐了,因为有大量反复计算,因为 计算某个数的倍数 是否为素数的时候呈现大量的反复计算,如果这个数比拟大那么对空间节约比拟多。 这样,素数筛的概念就被创造和应用。筛的原理是从返回后进行一种递推、过滤排序以来统计素数。 埃拉托斯特尼(Eratosthenes)筛法咱们看一个数如果不是为素数,那么这个数没有数的乘积能为它,那么这样咱们能够依据这个思维进行操作啊: 间接从前往后枚举,这个数地位没被标记的必定就是素数,如果这个数是素数那么将这个数的倍数标记一下(下次遍历到就不须要在计算)。如果不是素数那么就进行下一步。这样数值越大前面计算次数越少,在进行具体操作时候可借助数组进行判断。所以埃氏筛的核心思想就是将素数的倍数确定为合数。 假如刚开始全是素数,2为素数,那么2的倍数均不是素数;而后遍历到3,3的倍数标记一下;下个是5(因为4曾经被标记过);始终到n-1为止。具体流程能够看图: 具体代码为: boolean isprime[];long prime[];void getprime(){ prime=new long[100001];//记录第几个prime int index=0;//标记prime以后下标 isprime=new boolean [1000001];//判断是否被标记过 for(int i=2;i<1000001;i++) { if(!isprime[i]) { prime[index++]=i; } for(int j=i+i;j<1000000;j=j+i)//他的所有倍数都over { isprime[j]=true; } }}这种筛的算法复杂度为O(nloglogn);别小瞧多的这个logn,数据量大一个log可能少不少个0,那工夫也是十倍百倍甚至更多的差距。 ...

June 28, 2021 · 1 min · jiezi

leetcode讲解762.Prime Number of Set Bits in Binary Representation

题目Given two integers L and R, find the count of numbers in the range [L, R] (inclusive) having a prime number of set bits in their binary representation.(Recall that the number of set bits an integer has is the number of 1s present when written in binary. For example, 21 written in binary is 10101 which has 3 set bits. Also, 1 is not a prime.)Example 1:Input: L = 6, R = 10Output: 4Explanation:6 -> 110 (2 set bits, 2 is prime)7 -> 111 (3 set bits, 3 is prime)9 -> 1001 (2 set bits , 2 is prime)10->1010 (2 set bits , 2 is prime)Example 2:Input: L = 10, R = 15Output: 5Explanation:10 -> 1010 (2 set bits, 2 is prime)11 -> 1011 (3 set bits, 3 is prime)12 -> 1100 (2 set bits, 2 is prime)13 -> 1101 (3 set bits, 3 is prime)14 -> 1110 (3 set bits, 3 is prime)15 -> 1111 (4 set bits, 4 is not prime)Note:L, R will be integers L <= R in the range [1, 10^6].R - L will be at most 10000.题目地址讲解这一题同样是针对二进制表示进行出题,题目的意思是计算一个数的二进制表示中有多少个1,如果是素数个1,结果就加一。性能的提升点应该是在 isPrime 函数的实现上。我采用的是最普通的方法,从2到$\sqrt x$进行累加,判断x是否是素数,效率比较低。java代码class Solution { public int countPrimeSetBits(int L, int R) { int result = 0; for(int i=L;i<=R;i++){ int temp = i; int count = 0; while(temp>0){ if(temp%2==1){ count++; } temp >>= 1; } if(isPrime(count)){ result++; } } return result; } private boolean isPrime(int a){ if(a<=1){ return false; } for(int i=2;i<=Math.sqrt(a);i++){ if(a%i==0){ return false; } } return true; }} ...

January 7, 2019 · 2 min · jiezi