各位大一计算机萌新们,你们好,本篇博客会带领大家进行算法入门,给各位大一萌新答疑解惑。博客文章略长,可根据自己的需要观看,在博客中会有给大一萌新问题的解答,请不要错过。
入门简介:
算法,从字面意思来说就是计算方法,它是解决的问题的方法。一个问题有很多种方法解决问题,那么这很多种方法就是算法。官方给出的解释是:算法(Algorithm)是计算机科学中一个非常重要的概念,指的是一系列解决问题的清晰指令,算法代表着用系统的方法描述解决问题的策略机制。也就是说,算法是对特定问题求解步骤的一种描述,它是一组定义良好的计算过程,用于将输入数据(或称为问题的初始状态)转换成所需的输出形式(或称为问题的解)。
不懂没关系,我们继续往下看。
我们来举个简单的例子,热爱学习的你到图书馆借了10本书,由于自动借书机器的故障,你的一本算法书籍没有扫描登记混在了10本书当中,当你通过图书馆门禁时,警报突然响了, 惊慌失措的你立马查看是哪一本书没有登记,你把借阅的10本书一本一本的通过门禁,看看哪一本没有登记。坐在旁边的门卫大爷看不下去了,立马抢夺过来,门卫大爷首先把10本书分成两组,每5本一组,首先把任意一组通过门禁,如果警报响起未登记的书就在这一组里面,否则在另外一组里面。然后把警报响起的那组再分成两组,一组3本,一组2本,任意一组通过门禁,如果是2本的那一组警报响起的话,把这2本再分成2组,分别是每组1本,再分别通过门禁就会知道是哪一本没有登记了,如果是3本的那组警报响起的话,再把3本分成两组,分别是2本、1本,若是2本的警报响起,再分成两组,那么就可以找到了。
看完上面的例子,你是不是对算法有了稍微的了解了,由上面的例子我们来看,如果是一本一本的通过门禁,如果运气真的很差,就是在第10次才能检测出没有登记的书籍。如果是按照门卫大爷的方法,最坏的情况下,第4次就可以检测出没有登记的书籍,最坏的情况如下:第一次5本书一组,警报响了,把5本分成3本、2本两组,3本的那组响了,3本分成2本、1本两组,2本的那组响了,把2本分成每本一组,再通过一次就可以检测出来。此时你不禁感叹道算法这么厉害吗?
算法有哪些
算法在中国古代文献中称为“术”,最早出现在《周髀算经》、《九章算术》。距今不知道有多少种算法,但是ACM竞赛里常考的就一张图片搞定。下面放一张ACM队里培训常用得一张图片。里面涉及到了很多常用的算法,这些算法根据难度分为初级、中级、高级。
上面算法有非常多,如果你立志于拿acm金牌,参加World Final,那么这些都要熟练掌握,如果是大一小白,先从简单的学起来,像基本算法、搜索、动态规划、数据结构,再慢慢的去学习中级的算法,这些是一名acmer必须要掌握的基础。像非常难的算法,而且你只要能拿一个铜牌就比较满意。例如网络流、A*算法、欧拉函数等高级算法不需要学,下面放一本书中的算法难度分类。
如果上面看起来比较费劲可以看一下下面这张,一位资深acmer的经验总结。
快问快答
博主以自己大学算法经历给各位大一新生总结出了几个比较常见的问题,以及对不正经问题的回答,可以让大一计算机新生少踩很多坑。希望对大家有所帮助。
上面介绍完有关算法的问题,下面带领大家入一下门,算法评价标准最重要的就是时空复杂度,分别是时间复杂度、空间复杂度,在做题的是必须要考虑的问题,是评价一个算法好坏的标准,下面将会带大家认识一下它们。
时空复杂度
根据上面图书馆借书的例子,我们知道用了两种方法来查找没有登记的书,这两种方法的好坏评价标准为时间复杂度和空间复杂度。那么我们抛砖引玉,评价算法好坏的标准就是时间复杂度和空间复杂度。一般在题目开始上方会有此类限制例如:1s,128MB、2s,256MB,这是在告知你的算法设计的时空复杂度。如果超出了时间限制会Time Limit Exceeded(TLE)超出内存限制会Memory Limit Exceeding(MLE)。
时间复杂度:
时间复杂度是衡量算法执行效率的一个重要指标,它描述了算法执行时间随输入数据规模增长的变化趋势。时间复杂度通常用大O表示法来描述,它反映了算法在最坏情况下的性能。
- 大O表示法:用来描述算法的时间复杂度,表示为O(f(n)),其中 f(n) 是输入规模 n 的函数。
- 常数时间:表示算法的执行时间不随输入规模的变化而变化,记为O(1)。
- 线性时间:表示算法的执行时间与输入规模成正比,记为O(n)。
- 对数时间:表示算法的执行时间与输入规模的对数成正比,记为 O(logn)。
- 多项式时间:包括线性、二次、三次等,表示算法的执行时间是输入规模的多项式函数,记为 O(n^k),其中 k 是常数。
时间复杂度的计算:
- 加法法则:如果算法由多个部分组成,总的时间复杂度是各个部分时间复杂度的最大值,即O(f(n))+O(g(n))=O(max(f(n),g(n)))。
- 乘法法则:如果算法中的两个部分是顺序执行的,总的时间复杂度是两部分时间复杂度的乘积,即O(f(n))×O(g(n))=O(f(n)⋅g(n))。
- 忽略常数因子:在大O表示法中,常数因子、低阶项和系数通常被忽略,因为它们对算法的增长趋势影响较小。
上面例子第一种方法一本一本的去检测最坏的情况下是10次,在程序中我们只需要一个for循环遍历一遍即可所以时间复杂度为O(n),n=10。第二种方法叫二分,每一次对半查找,所以时间复杂度为O(logn),n=10。
一般来说一个循环(for、while)循环就是一个O(n),嵌套的话就是连乘。
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
for(int k=0;k<n;k++){
//操作
}
}
}
//上述时间复杂度为O(n^3)
如果不是嵌套,因为时间复杂度求的是最坏的情况,所以在整个程序里面抓大头,寻找最大的即可。 如果是时间复杂度有一个系数例如O(2*n),我们一般忽略前面的系数,记为O(n)。
for(int i=0;i<n;i++){
//操作
}
for(int j=0;j<m;j++){
//操作
}
for(int k=0;k<p;k++){
//操作
}
//上述时间复杂度为O(max(n,m,p))
常见的时间复杂度
- O(1):常数时间复杂度,如直接访问数组的某个元素。
- O(n):线性时间复杂度,如遍历一个包含 �n 个元素的数组。
- O(logn):对数时间复杂度,如二分查找。
- O(n^2):如冒泡排序和插入排序。
- O(2^n):指数时间复杂度,如解决某些组合问题。
现在博主教一下大家如何判断是否超出时间复杂度,我们以1s限制为例,例如时间复杂度为O(n^2),当n=1000时,带入大约是10^6,当得到的数值<=10^7,一定是可以解决此题的,1s在C++代码操作次数大约在10^7~10^8之间。当在这一个范围之内看你运气了,当大于等于10^8,这个算法就是不好的算法,完全解决不了此题。
空间复杂度:
空间复杂度是衡量算法在执行过程中所需的存储空间大小的指标。它与时间复杂度一样,是算法分析中的一个重要概念。空间复杂度通常用大O表示法来描述,它反映了算法在执行过程中所需的存储空间随输入数据规模增长的变化趋势。
- 大O表示法:用来描述算法的空间复杂度,表示为O(f(n)),其中f(n) 是输入规模 n 的函数。
- 常数空间:表示算法的存储空间需求不随输入规模的变化而变化,记为 O(1)。
- 线性空间:表示算法的存储空间需求与输入规模成正比,记为O(n)。
- 多项式空间:表示算法的存储空间需求是输入规模的多项式函数,记为O(n^k),其中 k 是常数。
- 指数空间:表示算法的存储空间需求是输入规模的指数函数,记为O(2^n)。
空间复杂度的计算
- 总空间:包括算法执行过程中所有变量和数据结构占用的空间总和。
- 辅助空间:除了输入数据本身占用的空间之外,算法在执行过程中额外使用的存储空间。
- 递归栈空间:对于递归算法,每次递归调用都会占用一定的栈空间,其空间复杂度与递归的深度有关。
常见的空间复杂度
- O(1):常数空间复杂度,如简单的变量赋值操作。
- O(n):线性空间复杂度,如存储 n 个元素的数组。
- O(logn):对数空间复杂度,如二叉树的深度遍历。
- O(n^2):如动态规划算法中可能使用的二维数组。
- O(n^k):多项式空间复杂度,如 k 维数组。
- O(2^n):指数空间复杂度,如某些图算法或组合算法。
一般来说在题目中空间复杂度不需要考虑,除非开了很多似用非用的空间。只要不超时解决了题目,那么你就是一名优秀的acmer。
由时间复杂度推算法
下面推荐一个非常好用的方法,根据题目给的数据范围推出应该用什么算法,总结由AcWing算法刷题平台yxc总结,原文链接:由数据范围反推算法复杂度以及算法内容 - AcWing
好了,说了这么多,希望对各位大一萌新有所帮助,文章长度限制,有许多问题没有涉及到,欢迎大家在评论区补充。如果有不懂或者有疑问的地方,欢迎在评论区讨论,也可以给博主发私信,看到必回。算法竞赛是一个很好的机会,希望各位大一新生把握此次机会,好好的体验一把,过了这个村就没这个店了。写此篇博客的目的是为了帮助大一新生进行算法入门解答,希望学弟学妹们少走博主走过的弯路。
执笔至此,感触彼多,全文将至,落笔为终,感谢各位读者的支持,如果对你有所帮助,还请一键三连支持我,我会持续更新创作。