算法基础认识
什么是算法
算法(Algorithm)是指用来操作数据、解决程序问题的一组方法。对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,但在过程中消耗的资源和时间却会有很大的区别
算法复杂度
时间复杂度
简述
- 是指执行当前算法所消耗的时间,我们通常用「时间复杂度」来描述
- 一个算法中的语句执行次数称为语句频度或时间频度,记为T(n)。时间频度T(n)中,n称为问题的规模,当n不断变化时,时间频度T(n)也会不断变化。但有时我们想知道它变化时呈现什么规律,为此我们引入时间复杂度的概念
- 算法的时间复杂度也就是算法的时间度量,记作:T(n) = O(f(n))。它表示随问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称「时间复杂度」
- 这种表示方法我们称为「 大O符号表示法」,又称为渐进符号,是用于描述函数渐进行为的数学符号
常见的时间复杂度量级
-
O(1),常数阶。表示该算法的执行时间(或执行时占用空间)总是为一个常量,不论输入的数据集是大是小,只要是没有循环等复杂结构,那这个代码的时间复杂度就都是O(1)
示例: int i = 1; int j = 2; int k = i + j; -
O(n),线性阶。表示一个算法的性能会随着输入数据的大小变化而线性变化。常见的如for循环语句,随着循环因子的增长而增加循环次数
示例: for (int i = 0; i < n; i++) { system.out.println("i:" + i) } -
O(n^2),平方阶。表示一个算法的性能将会随着输入数据的增长而呈现出二次增长。最常见的就是对输入数据进行嵌套循环。如果嵌套层级不断深入的话,算法的性能将会变为立方阶O(n^3),O(n^4),O(n^k)以此类推
示例: for (int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { system.out.println("i:" + i + ",j:"+j) } } -
O(2^n),指数阶。表示一个算法的性能会随着输入数据的每次增加而增大两倍,典型的方法就是裴波那契数列的递归计算实现
示例: public int demo(int num) { if (num <= 1) return num; return demo(num - 2) + demo(num - 1); } -
O(logn),对数阶
示例: int i = 1; while(i < n) { i = i*2; } -
O(nlogn),线性对数阶
示例: for(int i = 0; i< n; i++) { int j = 1; while(j < n) { j = j * 2; } }
空间复杂度
简述
- 是指执行当前算法需要占用多少内存空间,我们通常用「空间复杂度」来描述
- 空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的一个量度。同样反映的是一个趋势,一个算法所需的存储空间用f(n)表示。S(n)=O(f(n)),其中n为问题的规模,S(n)表示空间复杂度
- 一个算法在计算机存储器上所占用的存储空间,包括存储算法本身所占用的存储空间,算法的输入输出数据所占用的存储空间和算法在运行过程中临时占用的存储空间这三个方面
常见的空间复杂度
- S(1)。如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为 S(1)
- S(n)
复杂度速查表
- 参考文章:baijiahao.baidu.com/s?id=166219…
- 例如:
- 大O 复杂度曲线表
- 抽象数据结构的操作复杂度
- 数组排序
- 图操作
- 堆操作
常见算法
- 归并排序
- 二叉搜索树
- B+树索引
- 红黑树
- 哈希表
- 动态规划算法
- 贪心算法
- 启发式算法