一. 概念定义
最大公约数其实就是两个或两个以上的数所共有的约数中最大的约数(虽然感觉说了跟白说一样,但还是忍不住说一下)
1.1 gcd算法
gcd算法(全称,欧几里得算法):是通过辗转相除的方式计算两个数之间的最大公约数。
例如:我们要计算126和54的最大公约数gcd(126, 54)
126 % 54 = 18
gcd(126, 54) = gcd(54, 18)
54 % 18 = 0
54 / 18 = 3
所以3就是54和18的最大公约数,也就是126和54的最大公约数。
但为什么可以这样计算呢?
1.2 gcd的证明
我们要计算a,b两个数的gcd(a,b),我们可以得到 a = [a /b] * b + a % b,当a %b = 0时,则说明a / b为整数,b就是a的约数,当a % b不等于0时,我们先转化一下,令k = [a / b],c = a % b,则c = a - kb,我们假设a,b的一个公约数为 i ,则两边同时除 i ,我们可以的到c / i = a / i + kb / i,因为右边一定为整数,所以c / i 也是一个整数,即 i 时c的一个约数,也就说明a和b的公约数也是 a % b 的约数,所以上面的式子:
课后练习
1979. 找出数组的最大公约数
分析:
- 首先遍历数组nums,找到max和min
- 求gcd(max, min)
然后如何实现函数gcd呢,实现gcd有两种办法。
- 遍历出min约数,并判断该数是否能整除max,从而找出最大的公约数。
代码:
int gcd(int max, int min){
int ret = 0;
for(int i = 1; i <= min; i++){
if(min % i == 0 && max % i == 0){
ret = i;
}
}
return ret;
}
- 优化,利用欧几里得算法
int gcd(int a, int b){
return !b ? a : gcd(b, a % b);
}
int findGCD(int* nums, int numsSize){
int max = INT_MIN;
int min = INT_MAX;
for(int i = 0; i < numsSize; i++){
if(max < nums[i]){
max = nums[i];
}
if(min > nums[i]){
min = nums[i];
}
}
return gcd(max, min % max);
}