文章参考自书籍:《漫画算法-小灰的算法之旅》-魏梦舒

1.暴力枚举法

最大公约数是我们在小学都学过的,是最基本的数学知识,基本的我们都没有怀疑过它是否有更好的方法去计算。因为笔者当年的老师教我们从最小的数一直往上试,看看能不能同时被这俩整数整除,一直循环下去就能计算出最大公约数了。比如求10和25的最大公约数,大家或许会先试2,发现不是。然后试3,然后4...,一直到5。10/5=2,25/5=5. 2和5已经没有共同可分解的因数了。所以最大公约数是5. 如果用代码来写,可能会稍微有些不同,但是基本思路也是用一个循环去试出来最大的公约数。时间复杂度为O(N). 代码如下:

 public static int gcdV1(int a, int b) { int big = a>b ? a:b; int small = a1; i--) { if (0==(small%i) && 0==(big%i)) { return i; } } return 1; }

2. 辗转相除法

但是如果作为一道面试题,肯定不会这么简单,或许还有更好的方法等着我们去探索。这时候请出我们的欧几里得大神。

欧几里得

他提出了辗转相除法。这个算法是一条定理:两个正整数a和b (a>b), 它们的最大公约数等于a除以b的余数c和b之间的最大公约数。例如25和10,25除以10商2余5,那么25和10的最大公约数等同于10和5的最大公约数。所以在代码中我们可以用这条定理去递归,将比较大的整数运算简化成较小的运算,直到其中较小的数是1(能被较大数整除)为止。代码如下:

 public static int gcdV2(int a, int b) { int big = a>b ? a:b; int small = a

3. 更相减损术

辗转相除法的思路确实不错,但是其中的a%b取模运算在大整数的情况下性能会比较差劲。这时候还得看我国古代的《九章算术》提出的更相减损术。原理如下:

九章算术

两个正整数a和b (a>b),它们的最大公约数等于a-b的差值c和较小数b的最大公约数。例如25和10,25减去10的差是15,那么25和10的最大公约数等同于15和10的最大公约数。利用此原理我们可以写出如下代码:

 public static int gcdV3(int a, int b) { if (a == b) { // 边界条件 return a; } int big = a>b ? a:b; int small = a

4. 更相减损与移位相结合

更相减损法确实规避了取模这种性能差的运算,但是递归深度明显增加了。比如计算1000和1的最大公约数会递归999次。要是能结合辗转相除和更相减损的共同优点就好了。所以我们总结出了这样一种gcd算法。规则如下:

  • (1) 当a和b均为偶数时,gcd(a,b) = 2gcd(a/2, b/2)=2gcd(a>>1, b>>1);
  • (2)当a为偶数b为奇数时,gcd(a,b) = gcd(a/2, b)=gcd(a>>1, b);
  • (3)当a为奇数b为偶数时,gcd(a,b) = gcd(a, b/2)=gcd(a, b>>1);
  • (4)当a和b均为奇数时,先利用更相减损术一次 gcd(a,b) = gcd(b, a-b),此时a-b一定为偶数,然后又可以套用上面的规则继续计算了。

例如我们还是计算25和10的最大公约数,步骤如下。

1.gcd(25,10) = gcd(25, 5)

2.gcd(25,5) = gcd(20,5) // 更相减损术

3.gcd(20,5) = gcd(10,5)

4.gcd(10,5) = gcd(5,5)

5.gcd(5,5)因为两数想等,所以最大公约数是5 // 更相减损术

哦可,Talk is cheap, show U the code.

 public static int gcdV4(int a, int b) { if (a == b) { // 边界条件 return a; } if (0==(a&1) && 0==(b&1)) { return gcdV4(a>>1, b>>1)<<1; } else if (0==(a&1) && 0!=(b&1)) { return gcdV4(a>>1, b); } else if (0!=(a&1) && 0==(b&1)) { return gcdV4(a, b>>1); } else { int big = a>b ? a:b; int small = a

注:(a&1)==0说明a是偶数,否则是奇数

5. 最小公倍数

最小公倍数等于: (a*b)/gcd(a,b),这样求解最小公倍数也不在话下了。

作者 @没有故事的老大爷

python辗转相除法最大公约数和最小公倍数_小灰算法(二): 可能是小学老师没教你的最大公约数算法...相关推荐

  1. c语言最大公约数和最小公倍数_五年级数学最大公因数最小公倍数 练习

    五年级数学最大公因数最小公倍数-练习 一.填空. 1.把36分解质因数是(            ),把60分解质因数是(        ). 2.自然数a除以自然数b,商是15,那么a和b的最大公因 ...

  2. c语言最大公约数和最小公倍数_五年级奥数课堂之七:公因数和公倍数

    乘积尾0的个数 公因数和公倍数的基本概念 公因数的释义 给定若干个整数,如果有一个(些)数是它们共同的因数,那么这个(些)数就叫做它们的公因数.而全部公因数中最大的那个,称为这些整数的最大公因数. 公 ...

  3. python输出两个整数的最大公约数和最小公倍数_编程实现输入两个整数,输出其最大公约数和最小公倍数。...

    展开全部 举例:输入两个正整数m和n,输出它们的最小公倍数和最大公约数.62616964757a686964616fe58685e5aeb931333431353936 代码: #include in ...

  4. python计算无穷级数求和常用公式_傅里叶变换(二) 从傅里叶级数到傅里叶变换...

    在上一部分当中,得到了利用三角函数表示周期函数的方法,但是对于非周期函数就...凉了.所以有什么办法吗?没办法(划掉).这时候我们就需要拿出来我们的黑科技--傅里叶变换. 一.傅里叶级数的推广 当然这 ...

  5. python中一元二次方程的虚根_一元二次方程的概念和习题(老师用)

    一元二次方程的概念和习题 定义: 只含有一个未知数,且未知数的最高次数是 2 的整式方程叫做一元二次方程. 一元二次方程有三个特点: (1) 只含有一个未知数: (2) 未知数的最高次数是 2 : ( ...

  6. python打地鼠包老师_“打地鼠式”抽背?小学老师自创新式背诵法,让孩子自愿背书...

    文|齐姐育儿本文为原创文章,欢迎个人转载分享~提起背诵,可谓是很多人的童年"黑暗"回忆.每次上课,老师的一句"接下来我们找一个同学来背诵这篇课文".大部分学生的 ...

  7. 三种算法求两个正整数的最大公约数和最小公倍数;求三个数的最大公约数和最小公倍数

    第二次作业 题目:求两个正整数的最大公约数和最小公倍数. 基本要求:1.程序风格良好(使用自定义注释模板),两种以上算法解决最大公约数问题,提供友好的输入输出. 提高要求:1.三种以上算法解决两个正整 ...

  8. 求最大公约数和最小公倍数-python3

    """ 求最大公约数和最小公倍数Version: 1.0.0 Author: Catherine Data: 2019-03-11 """d ...

  9. 费氏(Fibonacci)数列、最大公约数,最小公倍数

    费式数列 说明 Fibonacci为1200年代的欧洲数学家,在他的着作中曾经提到:「若有一只免子每个月生一只小免子,一个月后小免子也开始生产.起初只有一只免子,一个月后就有两只免子,二个月后有三只免 ...

  10. 最大公约数和最小公倍数问题

    1.问题描述 求两个数的最大公约数和最小公倍数 2.问题要求 基本要求: 1.程序风格良好(使用自定义注释模板),两种以上算法解决最大公约数问题,提供友好的输入输出. 提高要求: 1.三种以上算法解决 ...

最新文章

  1. Jmeter学习——11
  2. Java黑皮书课后题第9章:9.2(Stock类)遵照9.2节中Cirlce类的例子,设计一个名为Stock的类
  3. c primer plus(第五版)读书笔计 第二章(3)
  4. 【面试】彻底理解 IO多路复用
  5. linux版本的redis bin,redis-4.0.2.tar.gz for centos的linux系统版本下载(安装详细步骤)...
  6. 【报告分享】2019年全球数字化风险调查报告-德勤.pdf(附下载链接)
  7. java 内部类_Java内部类总结有哪些 没有基础该怎么学Java?
  8. m3u8格式的视频链接怎么在自己电脑上播放
  9. 远控免杀专题10--TheFatRat免杀
  10. 分析光固化3D打印的优势
  11. 计算机表格布局,修改Word2007的表格布局
  12. Java实习生常规技术面试题每日十题Java基础(五)
  13. 高级网格交易学习笔记
  14. 企业高管和高收入人群必读的税务筹划策略!
  15. 《舞!舞!舞!》读后感
  16. Bzoj4763 雪辉
  17. 淘宝买零件组装一台手机,可以正常使用,想自己组装手机的可以看下
  18. 新买的键盘部分按键不好使失灵
  19. Linux 使用curl认证深信服上网行为管理
  20. 调节音量的各个方法——AudioManager的使用

热门文章

  1. 12.程序员的自我修养---系统调用与API
  2. 26.TCP/IP 详解卷1 --- Telnet 和 Rlogin : 远程登录
  3. 2. JavaScript Boolean 对象
  4. .net core 介绍好文章
  5. xcode中遇到的英文名词(更新)
  6. 2010-10-08在浏览器中兼容+jQuery3
  7. hdu 1561 树形dp+分组背包
  8. java基础杂谈(二)
  9. Intent以及IntentFilter详解 1
  10. 【IDEA】报错:Warning:java: 源值1.5已过时, 将在未来所有发行版中删除