声明: 本文主要作为作者的复习笔记,由于作者水平有限,难免有错误和不准确之处,欢迎读者批评指正.
数据结构
计算机存储和组织数据的方式;
数据结构关心的是数据怎么高效读写的问题;
算法
在特定的数据集上进行的一系列计算步骤,称为算法;
算法关心的是数据怎么使用的问题;
评价算法的好坏的两种维度: 时间效率和空间效率
- 时间复杂度
主要衡量一个算法的运行速度(不是实际计算机的运行速度,而是理论值,在所有计算机上通用的描述); - 空间复杂度
主要衡量一个算法正常执行所需要的额外空间大小,不是当前数据集本身占用的空间;
所谓的额外空间: 为了解决这个问题,新开辟的内存大小;
时间复杂度
- 不是具体的时间,在计算机领域,其实是一个数学函数; 因为不同的计算机硬件不同,相同的算法在不同的CPU、内存这些硬件上具体执行的时间都会有差异,而且有可能差异还很大; 利用数学函数,描述一个算法的基本操作的执行次数,就是我们讨论的时间复杂度;
- 时间复杂度一定要看执行次数和传入的变量之间的关系; 基本语句无论传入多大的数值,这个语句只执行一次,因此不统计;
- 时间复杂度不一定要统计具体的执行次数,只需要描述出算法的大概执行次数,保留对算法影响最大的某一项即可,该项就可以表示该算法的时间效率;
- 使用大O渐进表示法(数学符号,表示渐进函数)来描述一个算法的时间效率;
- 常见的时间复杂度有O(1)、O(N)、O(N ^ 2)、O(logN);
推导大O阶的方法
- 用常数1来代替函数中所有的加法常数(只要是常数、常量,无论常量有多大,统统用1替代);
- 只保留函数的最高阶项,所有的低阶省略不计;
- 若最高阶项存在,且项数不为1,统一都将最高阶的项数看做1;
- 先看最高阶在哪,低阶全部省略,若没有最高阶变量参与,统一都是常数1;
一个算法的时间复杂度存在最好、最坏、平均时间复杂度
- 最好
任意输入的数据,最小的执行次数(算法的下界); - 最坏
任意输入的数据,最大的执行次数(算法的上界); - 平均
任意输入的数据,平均的执行次数;
衡量一个算法的时间复杂度
- 平常衡量一个算法的时间复杂度取上界,即我们考虑的时间复杂度一般都看最坏情况; 使用大O阶时间复杂度来描述最坏情况就是整个算法的时间复杂度;
- 大O阶看的是变量的最高阶,若存在多个输入变量,各个变量的最高阶都需要保留; 比如变量N和变量M,无法得知谁大谁小,推导大O阶时,N和M都保留其最高阶O(N + M);
- 虽然算法的时间复杂度主要就是看循环次数,但是要注意循环次数是否和变量有关系; 若循环的次数就是一个常量,统一都看做O(1);
- 不一定代码中循环嵌套的越多就一定越慢,要分析具体的循环次数; 有可能同一道题的解法,不同的代码三层循环的速度比一层循环还快;
空间复杂度
算法执行过程中,额外开辟的空间大小;
- 空间复杂度描述一个算法额外开辟的临时变量个数,也是使用大O阶渐进表示法来描述空间复杂度;
- 已有空间: 通过外界向算法/函数传入的,不统计传入的变量N就算已有空间;
- 临时开辟的额外空间: 算法/函数内部创建的新空间;
- 常见的空间复杂度有O(1)、O(N);
非递归函数的空间复杂度
看函数内部new了什么;
递归函数的空间复杂度
看展开次数,每调用一次函数,都会额外的在栈上开辟栈帧空间;
若某些题目告知,空间复杂度要求为O(1) => 此时不能开辟新的数组,也不能使用递归;