前言
文章参考自:《算法零基础100讲》第14讲
最小公倍数概念
两个数 a 和 b 的最小公倍数是指能同时被 a 和 b 整除的最小倍数。
记作:
lcm(a, b)
特殊地,当 a 和 b 互素时,最小公倍数为 lcm(a, b) = a * b。
在上一节中已经学到利用辗转相除法求的最大公约数,gcd(a, b),若要求最小公倍数,就得先求最大公约数。
详细推导过程可参考:《算法零基础100讲》第14讲
代码实现
先复习一下最大公约数函数:
int gcd(int a, int b)
{
return !b ? a : gcd(b, a % b);
}
根据概念以及公式,可写出最小公倍数的函数:
int lcm(int a, int b)
{
return a * gcd(a, b) / b;
}
练习题
代码实现
#define CAPACITY 200001
int Exist[CAPACITY];
//辗转相除, 递归方法求最大公约数
int gcd(int a, int b)
{
return !b ? a : gcd(b, a % b);
}
//比较两个数中的最大值
int Max_Int(int a, int b)
{
return a > b ? a : b;
}
int countDifferentSubsequenceGCDs(int* nums, int numsSize)
{
//判空
if (NULL == nums) return 0;
//将数组数据置为0
memset(Exist, 0, sizeof(Exist));
int max = 0, ans = 0;
//标记题目给出的数组中的值,并且找出最大值
for (int i = 0; i < numsSize; ++i)
{
Exist[nums[i]] = 1;
max = Max_Int(max, nums[i]);
}
//枚举所有可能存在的最大公约数
for (int i = 1; i <= max; ++i)
{
int tmp = 0;
for (int j = i; j <= max; j += i)
{
if (Exist[j] != 0)
{
tmp = gcd(tmp, j);
}
}
//如果这个最大公约数等于i,就记录一次
if (tmp == i)
{
ans++;
}
}
return ans;
}
谢谢收看