楔子 -- 青蛙跳台阶一只青蛙一次可以跳上一级台阶,也可以跳上二级台阶,求该青蛙跳上一个n级的台阶总共需要多少种跳法 。
分析: 当n=1的时候 , ①只需要跳一次即可;只有一种跳法 , 即f(1)=1;
当n=2的时候,①可以先跳一级再跳一级,②也可以直接跳俩级;共有俩种跳法,即f(2)=2;
当n=3的时候,①一阶一阶跳即可;②他可以从一级台阶上跳俩阶上来③也可从二级台阶上跳一阶上来;即共有f(3)=f(2)+f(1);
【再谈前端算法,你这回明白了吗?】所以当有n阶台阶时,且当n>2的时候,根据上面式子可推导出→ f(n)=f(n-1)+f(n-2)
文章插图
图片
所以很直白的看出就是个 斐波那契数列 ,有一点不同的是 , 斐波那契数列从1,1,2,3,5,8,13…开始的,而我们这是以1,2,3,5,8,13…开始的,少了前面的1
什么是算法解决一系列问题的具体步骤
算法是一组用于解决特定问题或执行特定任务的有限步骤序列 。这些步骤按照确定的顺序执行,以达到所需的结果 。在计算机科学中,算法通常用于描述数据处理、自动化处理和数学运算的过程 。算法可以用来解决各种问题,包括排序、搜索、路径规划等 。
算法实例 :实现一个LRU缓存LRU是Least Recently Used(最近最少使用)的缩写 。
在计算机科学中,LRU是一种页面置换算法,通常用于操作系统的虚拟内存管理中 。
该算法根据页面(或者其他资源)的最近使用情况来进行置换,当需要置换时,选择最近最少被使用的页面进行替换 。
这样可以保证最常用的页面保留在内存中,从而提高性能 。
实例:vue keep-alive 缓存
LRU -- 最近使用
实现 LRUCache缓存 , 有一个大小 const lru = new LRUCache(capacity)
提示
const lru = new LRUCache(2)lru.put(1,1)lru.put(2,2) // {1:1,2:2}lru.get(1)lru.put(3,3) // {1:1,3:3}lru.get(2) // -1 (找不到)lru.put(4,4)// {4:4,3:3}
实现代码// 函数的 get 和 put 必须以 O(1)的时间复杂度运行 // get , 得是个hash(Map,Set) , 而不能是数组// ES6 迭代器const LRUCache = function(capacity){ this.cacheQueue = new Map() this.capacity = capacity }LRUCache.prototype.get = function(key){if(this.cacheQueue.has(key)){ // 如果找到了,这个key对应的value要提升新鲜度const result = this.cacheQueue.get(key)// 删掉,然后再放进去,这样 , 这个就能在cacheQueue的队尾(队尾为最新鲜地方)this.cacheQueue.delete(key)this.cacheQueue.set(key,result)return result}return -1 // 如果没有找到key,则直接返回 -1 }LRUCache.prototype.put = function(key,value){if(this.cacheQueue.has(key)){// 如果找到了 , 删掉this.cacheQueue.delete(key)}if(this.cacheQueue.size >= this.capacity){// 删除map的第一个元素,即最长时间未使用的this.cacheQueue.set(key,value)this.cacheQueue.delete(this.cacheQueue.keys().next().value)} else {this.cacheQueue.set(key,value)}}
扩展:ES6 MapES6的Map是一种内置的数据结构,它存储键值对并允许你通过键快速查找值 。Map对象类似于对象,但不同之处在于Map的键可以是任意数据类型,而对象的键只能是字符串或Symbol 。
Map还保留了插入顺序 , 这意味着当你遍历一个Map对象时 , 它会按照插入顺序返回键值对 。
Map的创建和初始化:要创建一个新的Map,你需要使用new Map()语法 。
例如:
const myMap = new Map();
添加键值对:你可以使用Map对象的set()方法添加键值对 。例如:
myMap.set('key1', 'value1');myMap.set('key2', 'value2');
获取键值对:你可以使用Map对象的get()方法获取键对应的值 。例如:
const value1 = myMap.get('key1'); // 返回 'value1'const value2 = myMap.get('key2'); // 返回 'value2'
检查Map中是否存在某个键:你可以使用Map对象的has()方法检查Map中是否存在某个键 。例如:
const hasKey1 = myMap.has('key1'); // 返回 trueconst hasKey3 = myMap.has('key3'); // 返回 false
删除键值对:你可以使用Map对象的delete()方法删除键值对 。例如:
myMap.delete('key1');
遍历Map:你可以使用Map对象的keys()、values()或entries()方法遍历Map中的键或值 。例如:
for (const key of myMap.keys()) {console.log(key); // 输出键名}for (const value of myMap.values()) {console.log(value); // 输出值}for (const [key, value] of myMap.entries()) {console.log(key, value); // 输出键名和值}myMap.forEach((value, key) => {console.log(key + ' = ' + value);});
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 17个有用的CLI命令,作为前端工程师,你需要知道一下
- 前端的十个问题,你知道几个?
- 前端性能优化应该怎么做?
- 强化学习算法在资源调度与优化中的应用
- 时序分析中的常用算法,都在这里了
- C++编程实践:IP哈希负载均衡算法
- STL背后的设计原则:了解STL的迭代器、容器和算法的设计哲学
- 算法工程师年薪百万元,缺口百万
- 前端请求到后端API的中间件流程解析
- Vue 微前端开发的七大神器