📜  Java 求两个正整数的最大公约数.整数可能很大,因此您需要找到一个聪明的解决方案. - Java (1)

📅  最后修改于: 2023-12-03 15:16:01.476000             🧑  作者: Mango

Java 求两个正整数的最大公约数

题目描述

给定两个正整数,求它们的最大公约数。这两个正整数可能很大,因此需要找到一个聪明的解决方案。

解决方案
1. 暴力枚举

我们可以暴力枚举这两个正整数的所有可能的公约数,从最小的开始依次递增,直到找到它们的最大公约数。

public static int gcd(int a, int b) {
    int gcd = 1;
    for (int i = 1; i <= a && i <= b; i++) {
        if (a % i == 0 && b % i == 0) {
            gcd = i;
        }
    }
    return gcd;
}

但是,这种方法的时间复杂度为 $O(\min(a,b))$,当 $a$ 和 $b$ 较大时,会非常耗时。

2. 辗转相除法

辗转相除法,也称为欧几里得算法,是一种求两个正整数最大公约数的算法。

它的基本思想是用较大数除以较小数,然后用余数去除除数,再用余数去除上一个余数,如此反复,直到最终的余数为 0。此时,除数就是两个正整数的最大公约数。

public static int gcd(int a, int b) {
    while (b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

该算法的时间复杂度为 $O(\log(\min(a,b)))$,比暴力枚举要快很多。

3. 更相减损术

更相减损术,也是一种求两个正整数最大公约数的算法。

它的基本思想是用较大数减去较小数,然后用相减的结果去除较小数,再用余数去除相减的结果,如此反复,直到最终的余数为 0。此时,相减的结果就是两个正整数的最大公约数。

public static int gcd(int a, int b) {
    while (a != b){
        if (a > b){
            a = a - b;
        } else {
            b = b - a;
        }
    }
    return a;
}

该算法的时间复杂度很难估计,最坏情况下可能达到 $O(\max(a,b))$。

总结

无论是辗转相除法还是更相减损术,都可以求出两个正整数的最大公约数。但是,其中辗转相除法更为高效,而且也更容易实现。因此,建议在实际场景中优先选择辗转相除法。