算法学习系列之求最大公约数
来源:互联网 发布:淘宝火锅底料哪个好吃 编辑:程序博客网 时间:2024/06/01 21:54
特别说明:本文参考学习于Java语言程序设计进阶篇—Y.Daniel Liang著一书
欢迎大家一起学习交流,希望程序的世界有你相伴
题目
给定两个大于0的实数,求出他们的最大公约数。
解法
方法1
求两个数的最大公约数,不妨可以从1开始,判断1是否能被m,n整除,如果整除则1是m,n的约数,同理进行2,3,··· max(m,n)。最后在这些约数之间选出最大的那个(实际上,就是最后一个约数,因为1,2,···是递增的)。代码实现如下:
public static int gcd(int m, int n) { int gcd = 1; for (int k = 2; k <= m && k <= n; k++) { if (m % k == 0 && n % k == 0) gcd = k; } return gcd; }
时间复杂度
假设m>=n,很显然该算法的时间复杂度为O(n)。
优化
我们在写完算法的同时,还应有再思考一下,是否有更好的实现,毕竟没有一个程序是完美的,都是走在完美的路上。本方法是从1开始向上寻找约数。那么我们是否可以逆向思维,从上到下的去寻找最大公约数呢?
方法2
首先,我们求出m,n的最小值,不妨设之为n,那么从n开始判断是否能同时被n,m整除,如果能整除,那么n就是最大公约数(因为此时数列是递减的),否则判断n-1,···,1。代码实现如下:
public static int gcd(int m, int n) { int gcd = Math.min(m, n); while (gcd > 0) { if (n % gcd == 0 && m % gcd == 0) { break; } gcd--; } return gcd; }
时间复杂度
这个算法比前一个效率更高,但是它的最坏情况的时间复杂度依旧是O(n)。
优化
我们再仔细想想,还能不能有更好的算法,我们的计算是否还存在多余的部分。在整除里面,数字n的除数不可能比n/2大,因此我们可以利用该性质,继续优化我们的算法。
方法3
首先,我们求出m,n的最小值,不妨设之为n,我们首先判断n是否为n,m的最大公约数,如果相等,直接返回n。不相等的话,我们从n/2开始判断,之后判断n/2-1,···1。代码实现如下:
public static int gcd(int m, int n) { int gcd = Math.min(m, n); if (n % gcd == 0 && m % gcd == 0) return gcd; for (int k = gcd / 2; k >= 1; k--) { if (n % k == 0 && m % k == 0) break; gcd = k - 1; } return gcd; }
时间复杂度
易知该算法的时间复杂度还是O(n),但是也很容易的证明,该算法虽然时间复杂度和前两种一样,但是它的运算效率要比前两种高得多。
方法4
其实,求最大公约数的一个更有效的算法是在公元前300年左右由欧几里得发现的,这是最古老的著名算法之一。它可以递归地定义为:
用gcd(m,n)表示整数m,n的最大公约数:
- 如果m%n为0,那么gcd(m,n)为n。
- 否则,gcm(m,n)就是gcm(n,m%n)
不难证明这个算法的正确性。假设m%n=r,那么,m=qn+r,这里的q是m/n的商。能整除m和n的任意数字都必定也能整除r。因此gcd(m,n)和gcd(n,r)是一样的。其中r=m%n。该算法的实现如下:
public static int gcd(int m, int n) { if (m < n) { int temp = n; n = m; m = temp; } if (m % n == 0) return n; else return gcd(n, m % n); }
时间复杂度
我们可以证明最坏的情况的时间复杂度O(logn)
假设m>=n,我们可以证明m%n
- 算法学习系列之求最大公约数
- 算法学习十六----求最大公约数
- 算法学习之求两个数的最大公约数
- 算法学习---求最大公约数(Gcd算法)
- 【数据结构与算法】之求最大公约数
- Stein算法 求最大公约数
- 求最大公约数算法
- 求最大公约数的算法
- 算法----求最大公约数
- 求最大公约数的算法
- 求最大公约数的算法
- 求最大公约数算法
- [算法]求最大公约数
- 求最大公约数算法
- 求最大公约数的算法
- 求最大公约数的算法
- 欧几里德算法求最大公约数
- 欧几里德算法求最大公约数
- 将大数据,分批分段,插入数据库
- 我的第一篇博客
- 深入理解iOS开发中的BitCode功能
- 二进制中1的个数
- Python
- 算法学习系列之求最大公约数
- 命令相关
- 分治算法
- Kylin性能调优记——业务技术两手抓
- 三、Nio之Buffer
- VirtualBox安装Red Hat6.4
- 配置Kafka集群
- OJ_1181.求和
- Idea15 常用设置(一):JDK、SVN