目录
一、复杂度分析
A/时间复杂度
B/空间复杂度
C/分析技巧
二、枚举分析
A/枚举算法介绍
B/解空间的类型
C/循环枚举解空间
三、模拟算法
四、递归
A/递归介绍
递归的两个关键要素:
B/递归如何实现
C/递归和循环的比较
一、复杂度分析
A/时间复杂度
1、时间复杂度是衡量算法执行时间随输入规模增长的增率;
2、通过分析算法中基本操作的执行次数来确定时间复杂度;
3、常见的时间复杂度包括:常数时间 O(1)、线性时间 O(n)、对数时间 O(log n)、平方时间O(n^2)等。
4、在计算的时候我们关注的是复杂度的数量级,并不要求严格的表达式。
一般我们关注的是最坏时间复杂度,用O(f(n))表示,大多数时候我们仅需估算即可。评测机1秒大约可以跑2e8(2*10的8次方)次运算,我们要尽可能地让我们的程序运算规模的数量级控制在1e8以内。
B/空间复杂度
1、空间复杂度是衡量算法执行过程中所需的存储空间随输入规模增长的增长率。
2、通过分析算法中所使用的额外存储空间的大小来确定空间复杂度。
3、常见的空间复杂度包括:常数空间 O(1)、线性空间O (n)、对数空间 O(log n)、平方空间 (n^2)等。
一般我们关注的是最坏空间复杂度,用O(f(n))表示,大多数时候程序占用的空间一般可以根据开出的数组大小精确算出,但也存在需要估算的情况。题目一般不会卡空间,一般是卡时间。
C/分析技巧
1、理解基本操作:基本操作可以是算术运算(加法、乘法、位运算等)、比较操作、赋值操作等。
2、关注循环结构:循环是算法中常见的结构,它的执行次数对子时间复杂度的分析至关重要。
3、递归算法:递归算法的时间和空间复杂度分析相对复杂。需要确定递归的深度以及每个递
归调用的时间和空间开销。
4、最坏情况分析:对于时间复杂度的分析通常考虑最坏情况下的执行时间。要考虑输入数据使得算法执行时间达到最大值的情况。
5、善用结论:某些常见算法的时间和空间复杂度已经被广泛研究和证明。可以利用这些已知结果来分析算法的复杂度。
二、枚举分析
A/枚举算法介绍
枚举算法是一种基本的算法思想,它通过穷举所有可能的情况来解决问题。它的基本思想是并进行验证和比较,找到满足问题条件的最将问题的解空间中的每个可能的解都枚举出来,优解或者所有解
枚举算法适用于问题规模较小、解空间可穷举的情况。它的优点是简单直观,不需要复杂的数学推导,易于实现。但是,由于需要穷举所有可能的情况,对于问题规模较大的情况,枚举算法的时间复杂度可能会非常高,效率较低。
B/解空间的类型
解空间可以是一个范围内的所有数字(或二元组、字符串等数据),或者满足某个条件的所有数字。
当然也可以是解空间树,一般可分为子集树和排列树,针对解空间树,需要使用回溯法进行枚举(搜索的时候会讲到)。
我们目前仅使用循环去暴力枚举解空间,具体的解空间类型需要根据题目来理解构造。
C/循环枚举解空间
1、首先确定解空间的维度,即问题中需要枚举的变量个数。
例如当题目要求的是满足条件的数字时,我们可以循环枚举某个范围内的数字。如果要求的是满足条件的二元组,我们可以用双重循环分别枚举第一个和第二个变量,从而构造出一个二元组。
2、对于每个变量,确定其可能的取值范围。这些范围可以根据问题的性质和约束条件来确定。这一步往往是时间复杂度优化的关键
3、在循环体内,针对每个可能解进行处理可以进行问题的验证、计算、输出等操作。
三、模拟算法
模拟算法通过模拟实际情况来解决问题,一般容易理解但是实现起来比较复杂,有很多需要注意的细节,或者是一些所谓很“ 麻烦 ”的东西。
模拟题一般不涉及太难的算法,一般就是由较多简单且不好处理的部分组成的,考察选手的细心程度和整体的逻辑思维。
一般为了使得模拟题写的逻辑清晰一些,经常会写比较多的小函数来帮助解题,例如 int 和 string 的相互转换、回文串的判断、日期的转换、各种特殊条件的判断等等。
四、递归
A/递归介绍
概念:递归是指函数直接或间接调用自身的过程。
递归的两个关键要素:
a.基本情况(递归终止条件):递归函数中的一个条件,当满足该条件时,递归终止避免无限递归。可以理解为直接解决极小规模问题的发法
b.递归表达式(递归调用):递归函数中的语句,用于解决规模更小的子问题,再将子问题的答案合并成为当前问题的答案。
B/递归如何实现
过程:1.将大问题分解为规模更小的子问题;2.使用递归调用解决每个子问题;3.通过递归终止条件来结束递归。
设计时需注意的细节:1.确保递归一定能到递归出口,避免无限递归,这可能导致TLE(超时)、MLE(超内存)或RE(运行错误);2.考虑边界条件,有时候递归出口不止一个;3.避免不必要的重复计算,尽可能优化递归函数的性能。
C/递归和循环的比较
递归的特点:
1.直观、简洁,易于理解和实现;
2.适用于问题的规模可以通过递归调用不断减小的情况;
3.可以处理复杂的数据结构和算法,如树和图的遍历;
4.存在栈溢出风险(栈空间一般只有8MB,所以递归层数不宜过深一般不超过1e6层)。
循环的特点:
1.直接控制流程,效率较高;
2.适用于问题的规模没有明显的缩减,或者需要特定的迭代次数;
3.适合处理大部分的动态规划问题;在部分情况下,递归和循环可以相互转化。
前缀和
前缀和原理和特点
prefix表示前缀和,前缀和由一个用户输入的数组生成。对于一个数组a[ ](下标从1开始),我们定义一个前缀和数组prefix[ ]满足:,prefix有一个重要的特性,可以用于快速生成prefix: