最大公约数

求最大公约数

今天学习了一下求最大公约数的各种方法,及时总结。

Q:写一段代码,求两个数的最大公约数,尽量优化算法性能

获取最大公约数方法常被称为 getGreatestCommonDivisor(gcd)

1.0 暴力枚举

public int gcd(int a,int b){
  int big = Math.max(a,b);
  int small = Math.min(a,b);
  
  if(big%small == 0){
    return small;
  }
  
  for(int i = small/2; i > 1 ; i--){
    if(small%i == 0 && big%i == 0){
      return i;
    }
  }
  
  return 1;
}	
  • 这种写法效率低下,没有运用古人的智慧 O(∩_∩)O
  • 复杂度O(min(a,b))

2.0 辗转相除法(欧几里得算法)

欧几里得算法是用来求两个正整数最大公约数的算法。古希腊数学家欧几里得在其著作《The Elements》中最早描述了这种算法,所以被命名为欧几里得算法。

老外方法的核心原理: 两个正整数a和b(a > b),它们的最大公约数等于 a 除以b的余数c 和 b 之间的最大公约数。即:

gcd(a,b) = gcd(a % b , b)
public static int gcd(int a,int b){
		int big = Math.max(a,b);
  	int small = Math.min(a,b);

    if(big % small == 0){
    		return small;
    }
    return gcd(big % small , small);
}
  • 不适用于两数均较大的情况,会导致 a%b 取模运算性能变差。
  • 取模运算性能较差,复杂度近似为O(log(max(a,b)))

3.0 更相减损术

更相减损术是出自《九章算术》的一种求最大公约数的算法,它原本是为约分而设计的,但它适用于任何需要求最大公约数的场合。

国产方法核心原理:两个正整数a和b(a > b),它们的最大公约数等于 a - b 的差值c 和较小数b 的最大公约数。即:

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

    int big = Math.max(a,b);
    int small = Math.min(a,b);

    return gcd(big - small , small);
}
  • 不适用于两数大小差距悬殊的情况。例如 a = 10000,b = 1的情况
  • 不稳定,最坏情况下复杂度为O(max(a,b))

4.0 中外结合版

核心原理: 结合2.0和3.0以及位运算。

    public static int gcd(int a,int b){
        if(a == b){
            return a;
        }

        if((a&1)==0 && (b&1)==0){
            //a和b均为偶数时, gcd(a,b) = 2*gcd(a/2,b/2);
            return gcd(a>>1 , b>>1)<<1;
        }else if((a&1)==0 && (b&1)!=0){
            //a偶b奇时, gcd(a,b) = gcd(a/2,b);
            return gcd(a>>1 , b);
        }else if((a&1)!=0 && (b&1)==0){
            return gcd(a , b>>1);
        }else {
            //a和b均为奇数时,先使用更相减损术
            int big = Math.max(a,b);
            int small = Math.min(a,b);

            return gcd(big - small , small);
        }
    }
  • 通过位运算避免了取模运算性能较差的问题
  • 性能稳定
  • 复杂度为O(log(max(a,b)))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

椰子zii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值