最大公约数又称最大公因数,那么到底有几种方法求解呢?哪种可以称之为最优解?
需求
方法穿两个正整数参数,返回值就是他们的最大公约数,尽可能保证性能。
-
最low办法:暴力枚举,时间复杂度是O(min(a, b)))。
-
辗转相除法: 又名欧几里得算法(Euclidean algorithm),目的是求出两个正整数的最大公约数。它是已知最古老的算法, 其可追溯至公元前300年前。可以近似为O(log(max(a, b))),但是取模运算性能较差。
-
更相减损术:避免了取模运算,但是算法性能不稳定,最坏时间复杂度为O(max(a, b)))
-
更相减损术与移位结合:不但避免了取模运算,而且算法性能稳定,时间复杂度为O(log(max(a, b)))
法2: 辗转相除法
//方法入口
public static int getGreatestCommonDivisor(int numberA,int numberB){
int result = 1;
if(numberA > numberB)
result = gcd(numberA,numberB);
else
result = gcd(numberB,numberA);
result result;
}
//递归计算最大公约数
private static int gcd(int a,int b){
if(a%b == 0)
return b;
else
return gcd(b,a%b);
}
法3:更相减损术
public static gcd(int numberA,int numberB){
if(numberA == numberB)
result numberA;
if(numberA < numberB)
return gcd(numberB - numberA,numberA);
else
return gcd(numberA - numberB,numberB);
}
法4:更相减损术与移位结合
public static int gcd(int numberA,int numberB){
if(numberA == numberB)
result numberA;
if(numberA < numberB)
//保证参数A永远大于等于参数B,为减少代码量
return gcd(numberB,numberA);
else(
//和1做按位与运算,判断奇偶
if(!numberA&1 && !numberB&1)
return gcd(numberA>>1,numberB&1) << 1;
else if(!numberA&1 && numberB&1)
return gcd(numberA>>1,numberB);
else if(numberA&1 && !numberB&1)
return gcd(numberA,numberB>>1);
else
return gcd(numberA,numberA - numberB);
)
}
欢迎拍砖
参考:
https://mp.weixin.qq.com/s?src=3×tamp=1576810267&ver=1&signature=TXWBvv-9Mw0fWIbIFp2TPV1ftZV25CM0Wt-Ynu9nsJEcJpcHxhUZcT-kPEW3BTb9YmSU81hgqnt3lXjs9n4X2rz5jeH4pLSVjvIOQG-q-nyHyowUcWG5*MSrC6OPRcIXAsob6RZTiHYXc2uYCbWef9vX1-S3xdCeR3PcrPbNAKc=