前言
文章出自专栏 :《算法零基础100讲》第13讲
LeetCode 1979.找出数组的最大公约数
原题链接:找出数组最大公约数
分析
题目给出一个数组,求最大和最小值的最大公约数。
那首先要找到数组中的最大值和最小值。
我的方法:
1.先利用快排对数组排序,排完序第一个和最后一个数字就是最小值和最大值。
2. 利用辗转相除法求这两个数的最大公约数。
代码实现
//辗转相除法
//函数实现就是递归形式
int Divisor(int a, int b)
{
return !b ? a : Divisor(b, a % b);
}
int mycmp(const void* p1, const void* p2)
{
const int* a = (const int*)p1;
const int* b = (const int*)p2;
return *a - *b;
}
int findGCD(int* nums, int numsSize)
{
//快排
qsort(nums, numsSize, sizeof(int), mycmp);
int min = nums[0];
int max = nums[numsSize - 1];
return Divisor(min, max);
}
LeetCode1819. 序列中不同最大公约数的数目
原题链接 :1819. 序列中不同最大公约数的数目
分析
根据题意就要知道 需要枚举所有可能的最大公约数 ,若判断 i 是不是某个子序列的最大公约数,就需要判断数组中存在的值与 i,2i, 3i 这些数据进行gcd判断,若最后的最大公约数就是i, 那就记录一次。
代码
#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;
}
感谢大家观看~