算法
常见的基础算法:递归、排序、枚举
时间复杂度
常见的时间复杂度:
- 常数阶:O(1)
- 对数阶:O(logN)
- 线性阶:O(n)
- 线性对数阶:O(nlogN)
- 平方阶:O(n^2)
- 立方阶:O(n^3)
- 指数阶:O(2^N)
复杂度分析技巧:
- 看有几重循环,一重是 O(n),两重是 O(n^2),以此类推
- 如果有二分,则为 O(logN)
- 保留最高项, 去掉常数项
空间复杂度
快速排序
流程:
- 随机选择数组中的一个数 A,以这个数为基准
- 将其他数字跟这个数进行比较,比这个数小的放在其左边,大的放在其右边
- 经过一次循环后,A 的左边都是小于 A 的,右边都是大于 A 的
- 继续将左边和右边的数递归前面的过程
实现代码:
// 比较函数
function compare(a, b) {
if (a === b) {
return 0;
}
return a < b ? -1 : 1;
}
// 原地交换函数
function swap(array, a, b) {
[array[a], array[b]] = [array[b], array[a]];
}
// 划分操作函数
function partition(array, left, right) {
const pivot = array[Math.floor((right + left) / 2)];
let i = left;
let j = right;
while (i <= j) {
while (compare(array[i], pivot) === -1) {
i++;
}
while (compare(array[j], pivot) === 1) {
j--;
}
if (i <= j) {
swap(array, i, j);
i++;
j--;
}
}
return i;
}
function quick(array, left, right) {
let index;
if (array.length > 1) {
index = partition(array, left, right);
if (left < index - 1) {
quick(array, left, index - 1);
}
if (index < right) {
quick(array, index, right);
}
}
return array;
}
function quickSort(array) {
return quick(array, 0, array.length - 1);
}
使用:
const data = [25, 18, 66, 45, 77, 31, 96, 52];
console.log(quickSort(data));
二分查找
二分查找采用分治思想,时间复杂度是 O(logN)
场景:在一堆有序的数中找出指定的数
流程:
- 找到数组中间的数 A,与要找的数比较大小
- 如果 A 较大,则从前半部分查找,否则从后半部分查找
- 不断缩小数量级,每次比较都扔掉一半的数据,直到找完数组为止
题 目:在一个二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
function find(target, array) {
let i = 0;
let j = array[i].length - 1;
while (i < array.length && j >= 0) {
if (array[i][j] === target) {
return [i, j];
} else if (array[i][j] > target) {
j--;
} else {
return true;
}
}
return false;
}
const data = [
[1, 2, 3, 4],
[5, 9, 10, 11],
[13, 20, 21, 23]
];
console.log(find(10, data));