JS中的时间复杂度和空间复杂度
学习算法的基础就是明白时间和空间复杂度的计算,这样才能知道还有什么优化的地方。
时间复杂度
一些常见的时间复杂度及其排序(从快到慢):
- - 常数时间
- - 对数时间
- - 线性时间
- - 线性对数时间
- - 平方时间
- - 指数时间
- - 阶乘时间
算法的消耗不会随着变量的增长而增长,无论代码多少行时间复杂度都是
let n = 1
let n2= 2
// ...
通常出现在分治法或二分查找等场景中,每步操作将问题规模按照倍数减少。
function binarySearch(arr, target) {
let left = 0;
let right = arr.length - 1;
while (left <= right) {
let mid = Math.floor((left + right) / 2);
if (arr[mid] === target) return mid;
else if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1; // 未找到目标值
}
操作时间与输入数据的大小成正比。
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += arr[i];
}
通常出现在高效排序算法中,如快速排序、归并排序。
function mergeSort(arr) {
if (arr.length <= 1) return arr;
const mid = Math.floor(arr.length / 2);
const left = mergeSort(arr.slice(0, mid));
const right = mergeSort(arr.slice(mid));
return merge(left, right);
}
function merge(left, right) {
let result = [], l = 0, r = 0;
while (l < left.length && r < right.length) {
if (left[l] < right[r]) result.push(left[l++]);
else result.push(right[r++]);
}
return result.concat(left.slice(l)).concat(right.slice(r));
}
操作时间与输入数据大小的平方成正比,常见于简单的嵌套循环。
function fn() {
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
};
};
};
操作时间随着输入数据大小呈指数增长,常见于递归解决方案中。
function fn(n) {
if {n <= 2}{
return 1
}
return fun(n - 1) + fun(n - 2)
};
操作时间随着输入数据大小的阶乘增长,通常出现在全排列生成等问题中。
let results = [];
function backtrack(path, options) {
if (options.length === 0) {
results.push(path);
return;
}
for (let i = 0; i < options.length; i++) {
let newPath = path.concat(options[i]);
let newOptions = options.slice(0, i).concat(options.slice(i + 1));
backtrack(newPath, newOptions);
}
}
backtrack([], arr);
空间复杂度
const n = 1;
- 一维数组
const arr = []
- 链表
class ListNode {
constructor(value) {
this.value = value;
this.next = null;
}
}
const head = new ListNode(0);
- 哈希表(Object、Map、WeakMap、Set、WeakSet)
const obj = {}
const map = new Map()
const weakMap = new WeakMap()
const set = Set()
const weakSet = new WeakSet()
- 字符串
const str = ''
- 递归调用栈 一些递归算法,如果最大递归深度为 (n),那么其调用栈的空间复杂度也是 (O(n))。例如,计算斐波那契数列的简单递归实现:
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
- 二维数组
let matrix = [];
for (let i = 0; i < n; i++) {
matrix[i] = new Array(n).fill(0);
}