前端面试手写题系列 II
前端面试 手写题系列 已经完结,包含了以下的题目:
手写拍平数组 flat 手写防抖和节流函数 手写深拷贝 手写快排 手写 call、apply、bind 手写一个 sleep 函数 手写冒泡排序 函数柯里化 对象扁平化 手写 new 过程 求数组中的最大值 手写 instanceof 手写 foreach 函数 手写迭代器 手写 filter 实现一个 compose 函数 正则相关(去哪儿原题) 实现一个任务调度函数(得物原题) 数组转化为 tree 不使用 a 标签,实现 a 标签的功能 手写插入排序 LRU 算法 归并排序 求两个数组的交集、并集、补集、差集 提取 url 中的参数 实现一个洗牌函数 shuffle 希尔排序
1.LRU 算法
least recently used,缓存淘汰算法。
相当于有一个队列,但是这个队列有一定的长度,每一你可以执行 put get 操作,最新被操作的值需要被移动到队尾,表示最新被执行,如果 put 的长度超过队列本来的长度,就需要将队列的队头元素弹出,用来释放空间,然后将新 put 的元素放进来。
/**
* @param {number} capacity
*/
var LRUCache = function (capacity) {
// 缓存的长度
this.cap = capacity
// 使用哈希表
this.cache = new Map()
};
/**
* @param {number} key
* @return {number}
*/
LRUCache.prototype.get = function (key) {
//不存在key值,返回-1
if (!this.cache.has(key)) {
return -1;
}
//存在则返回key值
//返回该值之前需要将key值放到尾部,变为最近使用
let val = this.cache.get(key);
this.cache.delete(key);
this.cache.set(key, val);
//返回
return this.cache.get(key)
};
/**
* @param {number} key
* @param {number} value
* @return {void}
*/
LRUCache.prototype.put = function (key, value) {
if (this.cache.has(key)) {
// 更新 key 的值,替换掉原来的value值
this.cache.set(key,value);
//将key值放到尾部,变为最近使用
this.cache.delete(key);
this.cache.set(key, value);
return;
}
if (this.cache.size >= this.cap) {
// 链表头部就是最久未使用的 key
const oldestKey = this.cache.keys().next().value;
this.cache.delete(oldestKey);
}
// 将新的 key 放到尾部
this.cache.set(key, value);
};
关于 this.cache.keys().next().value;
2.归并排序
归并排序思路:
// 归并排序
function mergeSort(arr) {
if (arr.length < 2) {
return arr
}
let mid = Math.floor(arr.length / 2)
let leftArr = arr.slice(0, mid)
let rightArr = arr.slice(mid)
return merge(mergeSort(leftArr), mergeSort(rightArr))
}
function merge(leftArr, rightArr) {
let res = []
while (leftArr.length > 0 && rightArr.length > 0) {
if (leftArr[0] < rightArr[0]) {
res.push(leftArr.shift())
} else {
res.push(rightArr.shift())
}
}
if (leftArr.length !== 0) {
res.push(...leftArr)
}
if (rightArr.length !== 0) {
res.push(...rightArr)
}
return res
}
// 测试
let arr = [2, 1, 4, 3, 5]
console.log(mergeSort(arr))
3.求两个数组的交集、并集、补集、差集
两个数组:
arrA:[1,2,3,4,5]
arrB:[3,4,5,6,7]
考察的其实是 JavaScript 数组的常见 api 的使用,很多公司都会这么考察。
const arrA = [1, 2, 3, 4, 5]
const arrB = [3, 4, 5, 6, 7]
// 求交集
const intersection = arrA.filter(v => arrB.includes(v))
console.log(intersection) // [3, 4, 5]
// 求并集
const union = Array.from(new Set([...arrA, ...arrB]))
console.log(union) // [1, 2, 3, 4, 5, 6, 7]
// 求差集
const difference = arrA.filter(v => !arrB.includes(v))
console.log(difference) // [1, 2]
// 求补集
const complement = arrA.filter(v => !arrB.includes(v)).concat(arrB.filter(v => !arrA.includes(v)))
console.log(complement) // [1, 2, 6, 7]
手写题系列文章
前端手写题系列 I
前端手写题系列 II
前端手写题系列 III
前端手写题系列 IV
前端手写题系列 V
前端手写题系列 VI
前端手写题系列 VII
前端手写题系列 VIII
前端手写题系列 IX
前端手写题系列 X