前端面试算法学习记录
每天联系一个算法知识点,了解其内在,不仅应付面试,更应该学习其内涵
文章内容
- 冒泡排序
- 快速排序
- 选择排序
- 二分查找
- 斐波那契查找
- 函数柯里化(curry)
- 栈(用两个栈实现队列)
下一篇继续…
前提了解
时间复杂度:代码实现的量级的时间,有O(1),O(N),O(logN),O(NlogN),O(N*N)
空间复杂度:代码占用磁盘内存大小,比如:是否开辟新空间等
代码稳定性:若两个相同值排序后,没有交换位置,则稳定性好;反之,则不好
大前提
const arr = [101,92,53,2,1,0,6,34,8,74]
冒泡排序:
这样理解:
两层数据循环 每次交换位置
时间复杂度O(n*n) 稳定
说明:
优化点:
1. 加一个flag 优化点 可以减少排序步骤
2. 【进一步优化】 设置一个last 记录循环的最远距离 避免最后有序的内容重新再排列
function m_sort(arr) {
const len = arr.length
for (let i=0;i<len;i++) {
let flag = true
for (let j = 0; j<len-i-1;j++) {
if (arr[j] > arr[j+1]) {
flag = false
// [arr[j], arr[j+1]] = [arr[j+1], arr[j]]
temp = arr[j + 1]
arr[j + 1] = arr[j]
arr[j] = temp
}
}
if (flag)
break
}
return arr
}
// console.log(m_sort(arr))
快速排序:
function q_sort(arr) {
const len = arr.length
let mid = Math.floor(len / 2)
let left =[], right = []
if (len<=1) {
return arr
}
for (let i=0;i<len;i++) {
if (arr[i] < arr[mid]) {
left.push(arr[i])
} else {
right.push(arr[i])
}
}
return q_sort(left).concat(q_sort(right))
}
console.log('快速排序:', q_sort(arr))
选择排序
function c_sort(arr) {
let min = arr[0]
for (let i=1,len=arr.length; i<len;i++) {
if (arr[i] < min) {
min = arr[i]
}
}
return arr
}
console.log('选择排序:', c_sort(arr))
二分查找
条件:必须有序,若无序必须要先对数组进行排序
let arr1 = [1,2,3,4,5,6,96,110,156,159,196]
function t_search(arr1, target) {
let low = 0, high = arr1.length -1
while(low<=high) {
const mid = Math.floor((high - low)/2) + low
if (arr1[mid] === target) return mid
if (arr1[mid] < target) {
low = mid +1
} else {
high = mid - 1
}
}
return -1
}
斐波那契
leetcode (青蛙跳台阶问题)
尾递归实现
function fibonacci(n) {
if (n === 0 || n=== 1) return 1
return fibonacci(n-1) + fibonacci(n-2)
}
加缓存处理,可以使用数组或者对象存储
let cache
let ret
function fibonacci(n) {
cache = new Array(n+2).fill(0)
if (n === 0 || n=== 1) return 1
if (!cache[n]) {
ret = fibonacci(n-1) + fibonacci(n-2)
cache[n] = ret
}
return cache[n]
}
递归数据量会比较大,可以使用遍历方式进行计算
let cache
let ret
function fibonacci(n) {
cache = new Array(n+2).fill(0)
cache[0] = 1
cache[1] = 1
cache[2] = 2
for (let i =3;i<n;i++) {
cache[i] = cache[i-1] + cache[i-2]
ret = cache[i]
}
return ret
}
函数柯里化(curry)
eg: add(1)(2)(3)… add(1, 2, 3); add(1, 2)(3); add(1)(2, 3);
在这里插入代码片
栈
栈的特点:先进后出,想象成一个桶,想要拿出最下面的元素,必须先把上面的拿走
队列特点:先进先出,想象成一个水管,从头进去,从尾流出去
LeetCode:用两个栈实现队列
var CQueue = function() {
this.stack1 = []
this.stack2 = []
};
/**
* @param {number} value
* @return {void}
*/
CQueue.prototype.appendTail = function(value) {
this.stack1.push(value)
};
/**
* @return {number}
*/
CQueue.prototype.deleteHead = function() {
if(this.stack2.length) {
return this.stack2.pop()
} else {
while (this.stack1.length) {
var ret = this.stack1.pop()
this.stack2.push(ret)
}
if(!this.stack2.length) {
return -1
} else {
return this.stack2.pop()
}
}
return this.stack2.pop() // 队列删除:是删除栈2的顶端的数
};