写在前面
辗转相除法求最大公约数
int gcd(int a,int b){
if(b>a) return gcd(b,a);
if(b==0) return a;
return gcd(b,a%b);
}
力扣1979. 找出数组的最大公约数
暴力求解
直接循环一次数组,不断更新最大值与最小值,最后用开头的函数返回最大公约数即可
小提示:最大数先定义为最小数(题中没有负数,所以我定义为了0),最小数先定义为最大数(0x3f3f3f3f是常用的int范围内的最大值)
class Solution {
int gcd(int a,int b){
if(b>a) return gcd(b,a);
if(b==0) return a;
return gcd(b,a%b);
}
public:
int findGCD(vector<int>& nums) {
int minn=0x3f3f3f3f,maxn=0;
for(int i=0;i<nums.size();i++){
maxn=max(maxn,nums[i]);
minn=min(minn,nums[i]);
}
return gcd(maxn,minn);
}
};
力扣1819. 序列中不同最大公约数的数目
观察gcd的特性
题目链接
假设
c
=
g
c
d
(
a
,
b
)
c=gcd(a,b)
c=gcd(a,b),则有
g
c
d
(
a
/
c
,
b
/
c
)
=
=
1
gcd(a/c,b/c)==1
gcd(a/c,b/c)==1。所以我们就可以利用这一个特性循环所有的元素,然后找出它的所有因子,然后求这个数除以这个因子和其他数除以这个因子的最大公因数。如果得到1就说明这个数是某几个数的最大公因数。(没看懂?那就看代码吧)
还是要提示一句子序列不是连续子序列!!!!
class Solution {
int gcd(int a,int b){
if(b>a) return gcd(b,a);
if(b==0) return a;
return gcd(b,a%b);
}
public:
int countDifferentSubsequenceGCDs(vector<int>& nums) {
vector<int> res(2e5+10);
for (auto t : nums) {
for (int i = 1; i <= t / i; i++) {
if (t % i == 0) {
res[i] = gcd(res[i], t / i);
res[t / i] = gcd(res[t / i], i);
}
}
}
int cnt=0;
sort(res.begin(),res.end());
for(auto t:res){
if(t==1) cnt++;
}
return cnt;
}
};