开启算法探索之旅

算法是计算机科学的灵魂,而深入理解算法设计与分析则是每一位技术爱好者的必修课。最近开始系统研读Anany Levitin的经典著作《算法设计与分析基础》,书中清晰的逻辑与丰富的案例让人受益匪浅。

为了将这份收获与思考沉淀下来,同时与更多志同道合的朋友交流,决定推出Daily-Algorithm系列博客。每篇内容将聚焦一个核心算法或关键概念,结合实践代码与直观示例,帮助大家逐步构建坚实的算法思维。

无论你是准备技术面试,还是希望提升编程能力,这个系列都将成为你的实用指南。期待与大家一起在算法的世界里探索、成长!

一、什么是算法

算法是一系列解决问题的明确指令。即给定符合规则的输入后能够在有限时间内获得相应的输出。直观的示意图如下:

算法的核心要点包括:算法步骤无歧义性、输入值域的准确性、同一算法形式的多样性、同一问题解法的多样性;需要指出的是对于同一问题,算法不同,往往思路也不同,造成解决问题的速度不同;接下来将会通过求解最大公约数的例子来进一步加深对于这几个性质的理解。

二、欧几里得算法

最大公约数的定义是这样的,两个不全为0的非负整数m,n的最大公约数记为gcd(m,n),gcd(m,n)就代表着能被m和n整除的最大整数【即m/gcd(m,n)与n/gcd(m,n)的余数均为0,两者结果均为非负整数】;而欧几里得算法就是重复应用等式gcd(m,n)=gcd(n,m mod n),其中m mod n代表m/n得到的余数;因为gcd(m,0)=m,可以明显看到,这里的m的取值记为开始时m,0的最大公约数;

举例来说,gcd(58,4)=gcd(4,2)=gcd(2,0)=2;

为了加深对这一算法的认识,我们用以下两个例题来练习一下:

解析:a.gcd(31415,14142)=gcd(14142,3131)=gcd(3131,1618)=gcd(1618,1513)=gcd(1513,105)=gcd(105,43)=gcd(43,19)=gcd(19,5)=gcd(5,4)=gcd(4,1)=gcd(1,0)=1,共10步;

b.(请阅读第三部分之后再来解答这道题目)由连续整数检测算法来解决gcd(31415,14142)需要14142步,则速度倍数为1414.2倍,约为1414倍;

下面给出一个更加结构化的算法层次:

用代码的形式来展示该算法如下所示:

对于最大公约数求解这一问题,同其他大多数问题一致,还有一些别的算法及思路;

三、连续整数检测算法

这一算法只基于最大公约数的定义:m和n的最大公约数就是能够同时整除它们的最大正整数;正因如此gcd(m,n)一定不大于m和n,所以先令t=min{m,n},接下来就开始简单粗暴的步骤,判断t是否能被m,n整除。如果能,则t即为gcd(m,n);如果不能,则接着尝试t-1;依此类推,不断地-1进行尝试,直至该值能被m,n整除。

下面是更清晰的分层表述

与欧几里得算法不同之处在于,如果说输入的m,n两值中有0存在,那么该算法将会输出错误的值,这就恰恰说明了输入的值域准确规范的重要性;

四、分解质因数

还有一种思路来求解最大公约数,就是对输入值进行拆分,即将m,n分别拆成多个质因数的乘积,然后将拆分后的结果进行比较,将相同的质因数乘积提取出来即为最大公约数;

例如:80=2*2*2*2*5;24=2*2*2*3

gcd(80,24)=2*2*2=8

然而,此算法要比欧几里得算法复杂得多,这也就意味着计算也比较慢,且这种表述也不能够称之为严谨的算法,因为其中在求解质因数时并没有给出详细准确的定义,该步骤仅仅要求求出一个质因数的列表,但并没有给出求出该质因数列表的具体要求及方法;

所以,下面我们解决了如何求解质因数列表这一问题,将这一表述进行补充才能够称这种方法算作一种算法;一个求解不大于给定整数n的连续质数序列的算法被称为“埃拉托色尼筛选法”。该算法的基本逻辑就是先初始化一个2到n的正整数序列,然后从2开始,消去除2以外的所有的2的倍数,接下来从3开始,消去除3以外3的倍数,依此类推,其中有些值4,6等已经被消去的那就直接跳过,依次进行直至结束,剩下的这些数全为质数。

那么这个算法结束要有什么限制呢?如果我们此时要消去的是p的倍数,那么我们首先考虑的是p*p,而不是p*2,...,p*(p-1)这些更小的值,因为它们已经被消去了,我们也可以通过这一点来避免对于某些数的重复消除,显然p*p不会大于n,p也不会大于n的开方,所以我们可以把是否符合p*p<=n来判断是否因该结束。

算法代码表示如下:(其中代表向下取整函数)

将埃拉托色尼筛选法应用于分解质因数来求解最大公约数,则该方法就可以成为一个合格的算法;

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐