算法面试题(1):判断一个数是否为素数

本系列博客习题来自《算法(第四版)》,算是本人的读书笔记,如果有人在读这本书的,欢迎大家多多交流。为了方便讨论,本人新建了一个微信群(算法交流),想要加入的,请添加我的微信号:zhujinhui207407 谢谢。另外,本人的个人博客 http://www.kyson.cn 也在不停的更新中,欢迎一起讨论

算法面试题(1):判断一个数是否为素数_第1张图片
算法(第4版)

知识点

  • 素数的概念
  • 算法优化

分析

要回答这道题,我们要先弄清楚什么数是素数(质数)。质数(prime number)又称素数,有无限个。质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数,这样的数称为质数。

答案

根据定义,得出最简单的代码,如下

public static boolean isPrime1(int N) {
    if (N < 2)
        return false;
    
    for (int i = 2; i < N; i++)
        if (N % i == 0)
            return false;
    return true;
}

这是根据其定义来写的算法,那他算不算最优解呢。
我们继续探讨,不难发现一个数的一半往后是不存在其因数的(除了该数本身)。比如,80的一半是40,超过40以后就不可能有其因数了。因此我们的程序可以优化成

public static boolean isPrime2(int N) {
    if (N < 2)
        return false;
    for (int i = 2; i < N / 2; i++)
        if (N % i == 0)
            return false;
    return true;
}

好,这样一来我们已经节省了一半的时间了。
接着我们继续优化。
代码如下:

public static boolean isPrime3(int N) {
    if (N < 2)
        return false;

    for (int i = 2; i * i < N; i++)
        if (N % i == 0)
            return false;
    return true;
}

好,代码已经写完了,大家知道其中的原因了吗

提高

还有比第三种效率更高的吗,群里的小伙伴给出了更好的解决方案

public static boolean isPrime4(int num) {
    // 两个较小数另外处理
    if (num == 2 || num == 3)
        return true;
    // 不在6的倍数两侧的一定不是质数
    if (num % 6 != 1 && num % 6 != 5)
        return false;
    int tmp = (int) Math.sqrt(num);
    // 在6的倍数两侧的也可能不是质数
    for (int i = 5; i <= tmp; i += 6)
        if (num % i == 0 || num % (i + 2) == 0)
            return false;
    // 排除所有,剩余的是质数
    return true;
}

代码索引

IsPrime.java

你可能感兴趣的:(算法面试题(1):判断一个数是否为素数)