左程云算法通关041 最大公约数、同余原理

本文介绍了欧几里得算法及其在求解最大公约数的应用,通过编程实现快速求解。同时探讨了最小公倍数的计算方法以及在LeetCode问题中的实际应用,涉及二分搜索和容斥原理。还提到了针对大整数运算的Stein算法和同余原理,以提高效率。
摘要由CSDN通过智能技术生成

最大公约数

1.欧几里得算法——辗转相除法

公式为gcd(a,b) = gcd(b,a mod b)

例如要求50,30最大公因数,过程为

50%30=20,余数不为0 ,继续递归gcd(30,20)

30%20=10,余数不为0 ,继续递归gcd(20,10)

20%10=0,余数为0,停止,gcd(10,0)此时10即是最大公因数

2.一行代码即可求出最大公约数

int gcd(int a,int b){
    return b==0? a:gcd(a%b);
}

 求最小公倍数

int lcm(int a,int b){
    return (long)a/gcd(a,b)*b;
}

3.证明过程

假设a,b是两个正整数,u是二者的公因子,并且a%b=r;

也就是我们要证明gcd(a,b)=gcd(b,r)

首先我们有a=k*b+r,k=0,1,2...

                  r=a-k*b,k=0,1,2...

并且我们知道a=s*u,b=t*u;代入可得

                 r=s*u-k*t*u=u*(s-kt);这说明u如果是a和b的公因子,那么u也是r的因子。

 我们假设b和r的公因子为m,b=m*v,r=n*v;

                 a=k*m*v+n*v=v*(k*m+n);这说明m如果是b和r的因子,那么也是a的因子

因此我们得出结果,a和b的公因数集合=b和r的公因数集合。

4.时间复杂度

若a>b,时间复杂度大致为O(log a)的三次方.

5.经典习题

 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

LeetCode878 第N个神奇数字

一个正整数如果能被 a 或 b 整除,那么它是神奇的。

给定三个整数 n , a , b ,返回第 n 个神奇的数字。因为答案可能很大,所以返回答案 对 10^9+ 7取模后的值。

本题思路:利用二分搜索和容斥原理。

粗略定出第n个数字的范围为(1,n*a)。因为假设没有b的加入,那么第n个神奇的数字必然是n*a,但是由于有b加入,所以搜索范围会缩短。

我们假设有一个函数f(x)可以计算出从1到x一共有多少个神奇的数字,那么我们就可以利用二分答案法来计算出第n个神奇的数字在哪里。那么核心点就在于如何找到这个f(x)

f(x):在1-x范围上,能被a整除的有x/a这么多数字,能被b整除的有x/b这么多数字,有些数字既能被a又能被b整除,所以我们计算重复了,应该减去这一部分,也就是x/lcm(a,b)。这和离散数学里的容斥原理是一样的。

class Solution {
    public int nthMagicalNumber(int n, int a, int b) {
        long lcm=lcm(a,b);
        long answer=0;
        for(long l=0,r=(long)n*Math.min(a,b),m=0;l<=r;){
            m=(l+r)/2;
            if(m/a+m/b-m/lcm >=n){
                r=m-1;
                answer=m;
            }
            else{
                l=m+1;
            }
        }
        return (int)(answer%1000000007);
    }
    public long gcd(long a,long b){
        return b==0?a:gcd(b,a%b);
    }
    public long lcm(long a,long b){
        return (long)a*b/gcd(a,b);
    }
}

6.Stein算法 

7.裴蜀定理

同余原理

为什么要用同余原理

两个整数a、b,若它们除以整数m所得的余数相等,则称a与b对于模m同余或a同余于b模m。

记作:a≡b (mod m)。

如果两个整数是32位或者64位,那么进行各种运算时间复杂度是O(1),但如果是自己随机用字符串转换过来的k位整数,进行加减操作时间复杂度为O(k),乘除时间复杂度为O(k²)

如果我们想要提高运算速度,必须在中间过程取模运算,将时间复杂度控制到O(1)。

加法同余原理

(a + b) % m的值等于 ((a % m) + (b % m)) % m这个就是加法的同余原理。

乘法同余原理

(a * b) % m的值等于  ((a % m) * (b % m)) % m

减法同余原理

(a - b) % m的值等于   ((a % m) - (b % m) + m) % m,加上m可以保证一定不是负数,并且m%m=0不会影响最后结果。

比如说75和17,我们计算(75-17)%7=2;   75%7=5,17%7=3,answer=(5-3+7)%7。

再比如72,18,(72-18)%7=5 ;              72%7=2;18%7=4;answer=(2-4+7)%7.

以上便是同余原理,除法的同余原理一般用不到,会在后面逆元的知识里进行讲解。

  • 26
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值