📅  最后修改于: 2023-12-03 15:16:01.476000             🧑  作者: Mango
给定两个正整数,求它们的最大公约数。这两个正整数可能很大,因此需要找到一个聪明的解决方案。
我们可以暴力枚举这两个正整数的所有可能的公约数,从最小的开始依次递增,直到找到它们的最大公约数。
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$ 较大时,会非常耗时。
辗转相除法,也称为欧几里得算法,是一种求两个正整数最大公约数的算法。
它的基本思想是用较大数除以较小数,然后用余数去除除数,再用余数去除上一个余数,如此反复,直到最终的余数为 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)))$,比暴力枚举要快很多。
更相减损术,也是一种求两个正整数最大公约数的算法。
它的基本思想是用较大数减去较小数,然后用相减的结果去除较小数,再用余数去除相减的结果,如此反复,直到最终的余数为 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))$。
无论是辗转相除法还是更相减损术,都可以求出两个正整数的最大公约数。但是,其中辗转相除法更为高效,而且也更容易实现。因此,建议在实际场景中优先选择辗转相除法。