衡量一个算法的好坏, 从时间复杂度和空间复杂度来全面分析,
算法的最优解: 先考虑时间复杂度再考虑空间复杂度

时间复杂度
常数阶O(1) : 算法的执行时间总是为常数, 不随数据量变化而改变
int k = i + j;
线性阶O(n) : 算法的执行时间随数据量的变化线性增长
for (int i = 0; i < n; i++) {
//TODO
}
平方阶O(n^2) :
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
//TODO
}
}
对数阶O(logn) : 2^x = n 得出 x = log₂n, while循环处理不一定都是线性的
int i = 1;
while (i < n) {
i = i * 2;
}
PS: N^M 就是 N * N * N ....(M个N相乘, 感觉都把数学内容都还给老师了)
线性对数阶O(n * logn) : 把时间复杂度为logn代码循环n遍
for(int m = 1; m < n; m++) {
i = 1;
while(i < n) {
i = i * 2;
}
}
空间复杂度
常数阶O(1) :
int i = 1;
int j = 2;
int m = i + j;
线性阶O(n) :
int[] m = new int[n]
for(int i = 1; i <= n; ++i) {
int j = i;
j++;
}
判断O(logn)
// 该时间复杂度判定方式
// n经过几次"除以m"操作后, 等于1?
// 1经过几次"乘以m"操作后, 等于n?
while(n) {
n /= 10;
}
何种情况下, 选择合适的算法
根据数据的规模来判定, 使用何种算法, 并不能简单通过时间复杂度来区分. 规模越大, 通过时间复杂度判定是越准确的. 这也是为啥? Arrays.sort(), 再数据量小的时候反而使用插入算法O(n^2)ps:特别注意的是计算时间复杂度的变量
O(k ^ 2 + nlogn + m) 其他项都不能进行省略
O(n ^ 2 + nlogn + n) == O(n ^ 2)
递归复杂度的计算
递归有相应的代价, 递归的深度是多少, 它相应所占据的
时间复杂度:
- 内部一次递归: 方法的时间代价 * 深度
- 内部多次递归: 可以通过树结构来脑补来进行判断
空间复杂度: 方法的空间代价 * 深度