最新不得不服,面试官手里那些秀你一脸的求质数大法,腾讯&字节&爱奇艺&网易&华为实习面试汇总

总结

我们总是喜欢瞻仰大厂的大神们,但实际上大神也不过凡人,与菜鸟程序员相比,也就多花了几分心思,如果你再不努力,差距也只会越来越大。

面试题多多少少对于你接下来所要做的事肯定有点帮助,但我更希望你能透过面试题去总结自己的不足,以提高自己核心技术竞争力。每一次面试经历都是对你技术的扫盲,面试后的复盘总结效果是极好的!

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

List list = new ArrayList<>();
for (int i = 2; i < n; i++) {
boolean bool = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
bool = false;
break;
}
}
if (bool) {
list.add(i);
}
}
// System.out.println(list);
return list.size();
}

带一些优化的暴力求质数

//带一些优化的暴力求质数
public static int getPrimes1(int n) {
if (n < 3) {
return 0;
}
//从3开始验算,所以初始值为1(2为质数)。
List list = new ArrayList<>();
list.add(2);
for (int i = 3; i < n; i++) {
//当某个数为 2 的 n 次方时(n为自然数),其 & (n - 1) 所得值将等价于取余运算所得值
//*如果 x = 2^n ,则 x & (n - 1) == x % n
//if(i % 2 == 0)
if ((i & 1) == 0) {
continue;
}
boolean bool = true;
//用 j * j <= i 代替 j <= i 会更好。
//因为我们已经排除了所有偶数,所以每次循环加二将规避偶数会减少循环次数
for (int j = 3; j * j <= i; j += 2) {
if (i % j == 0) {
bool = false;
break;
}
}
if (bool) {
list.add(i);
}
}
// System.out.println(list);
return list.size();
}

通过前面求得的质数对后面的质数进行判断

//通过前面求得的质数对后面的质数进行判断
public static int getPrimes2(int n) {
//存放质数得list
List list = new ArrayList<>();
//求质数从2开始
for (int m = 2; m < n; m++) {
//声明一个bool变量,看看是不是在list里面有能被整除得
boolean isPrime = true;
//常见得求质数开平方
int sqrt = (int) Math.sqrt(m);
//循环list,list里面都是求过得质数
for (Integer i : list) {
//如果以前得质数能被n整除,说明n不是质数,false,list不能添加n
//直接终止循环
if (m % i == 0) {
isPrime = false;
break;
}
//如果i大于当前这个数得开平方数,证明后面的已经不可能整除了
if (i > sqrt) {
break;
}
}
//如果当前循环内,没有被整除,即为质数,可以加入list,进行下一个循环
if (isPrime) {
list.add(m);
}
}
// System.out.println(list);
return list.size();
}

厄拉多塞筛法

//厄拉多塞筛法
public static int getPrimes3(int n) {
List list = new ArrayList<>();
boolean[] bools = new boolean[n];
for (int i = 2; i < n; i++) {
// 布尔类型的默认值为 假。所以在此处用了逻辑非(!)操作符。
if (!bools[i]) {
list.add(i);
for (int j = i + i; j < n; j += i) {
//只要是i的倍数,就证明不是质数,因为他有其他因子
//排除不是质数的数
bools[j] = true;
}
}
}
// System.out.println(list);
return list.size();
}

Bitmap对筛法的空间优化(主要是空间优化,当然也有效率优化)

/*
Bitmap对筛法的空间优化(主要是空间优化,当然也有效率优化)

这个的意思就是signs是记录的第几层,每一层分为8个
也就是int为32字节,每个字节是8个bit
(i & 31)==(i % 32)
(1 << (i & 31))这一步是为了满足位数
signs[i / 32]是为了看第几层
((signs[i / 32] & (1 << (i & 31))) == 0证明当前这一层的这一位并没有被记录
说明当前是个质数

循环:
循环中的j就是i的倍数,既然是倍数,就说明他不是质数
signs[j / 32] |= 1 << (j & 31);
在看这里,找到j的那一层,然后看j那一层那几位bit,如果有某一位有1存在,那这一位就是1
二进制下:
101 | 10 == 111
*/
public static int getPrimes4(int n) {
List list = new ArrayList<>();
//一个 int 变量占用 32 字节
//如果是在C#中,提供了点阵列(BitArray)数组,那个的可读性会好很多
int[] signs = new int[n / 32 + 1];
for (int i = 2; i < n; i++) {
//将元素和需确定得数字经行按位或运算,如果值改变,说明不存在该数字(未登记该数字),则其为质数。
//(当某个数为 2 的 n 次方时(n为自然数),其 & (n - 1) 所得值将等价于取余运算所得值)
//*如果 x = 2^n ,则 x & (n - 1) == x % n
//下面判断可以写成
//if ((signs[i / size] & (1 << (i % 32))) == 0)
if ((signs[i / 32] & (1 << (i & 31))) == 0) {
list.add(i);
for (int j = i + i; j < n; j += i) {
//登记该数字
signs[j / 32] |= 1 << (j & 31);
}
}
}
// System.out.println(list);
return list.size();
}

最后来看一下各个求质数方法的效果图(这里用的是一百万以内的质数)

这里附上全部代码

import java.util.ArrayList;
import java.util.List;

public class Primes {
public static void main(String[] args) {
long start = System.currentTimeMillis();
System.out.println(getPrimes(1000000));
long end = System.currentTimeMillis();
System.out.println(“最基础的暴力求质数” + (end - start) + “毫秒”);

start = System.currentTimeMillis();
System.out.println(getPrimes1(1000000));
end = System.currentTimeMillis();
System.out.println(“带一些优化的暴力求质数” + (end - start) + “毫秒”);

start = System.currentTimeMillis();
System.out.println(getPrimes2(1000000));
end = System.currentTimeMillis();
System.out.println(“通过前面求得的质数对后面的质数进行判断” + (end - start) + “毫秒”);

start = System.currentTimeMillis();
System.out.println(getPrimes3(1000000));
end = System.currentTimeMillis();
System.out.println(“厄拉多塞筛法” + (end - start) + “毫秒”);

start = System.currentTimeMillis();
System.out.println(getPrimes4(1000000));
end = System.currentTimeMillis();
System.out.println(“Bitmap对筛法的空间优化(主要是空间优化,当然也有效率优化)” + (end - start) + “毫秒”);

}

//最基础的暴力求质数
public static int getPrimes(int n) {
List list = new ArrayList<>();
for (int i = 2; i < n; i++) {
boolean bool = true;
for (int j = 2; j < i; j++) {
if (i % j == 0) {
bool = false;
break;
}
}
if (bool) {
list.add(i);
}
}
// System.out.println(list);
return list.size();
}

//带一些优化的暴力求质数

总结

面试建议是,一定要自信,敢于表达,面试的时候我们对知识的掌握有时候很难面面俱到,把自己的思路说出来,而不是直接告诉面试官自己不懂,这也是可以加分的。

以上就是蚂蚁技术四面和HR面试题目,以下最新总结的最全,范围包含最全MySQL、Spring、Redis、JVM等最全面试题和答案,仅用于参考

一份还热乎的蚂蚁金服面经(已拿Offer)面试流程4轮技术面+1轮HR

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

-qduqWbkI-1715658901241)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值