引言

队列这种数据结构,据瓶子君了解,前端需要了解的队列结构主要有:双端队列、滑动窗口,它们都是算法中是比较常用的数据结构。

因此,本节主要内容为:

  • 数据结构:队列(Queue)
  • 双端队列(Deque)
  • 双端队列的应用:翻转字符串中的单词
  • 滑动窗口
  • 滑动窗口应用:无重复字符的最长公共子串
  • 最后来一道 leetcode 题目:滑动窗口最大值问题

下面进入正文吧?

一、数据结构:队列

队列和栈类似,不同的是队列是先进先出 (FIFO) 原则的有序集合,它的结构类似如下:


常见队列的操作有:enqueue(e) 进队、 dequeue() 出队、 isEmpty() 是否是空队、 front() 获取队头元素、clear() 清空队,以及 size() 获取队列长度。

代码实现

function Queue() {  let items = []  this.enqueue = function(e) {    items.push(e)  }  this.dequeue = function() {    return items.shift()  }  this.isEmpty = function() {    return items.length === 0  }  this.front = function() {    return items[0]  }  this.clear = function() {     items = []   }  this.size = function() {    return items.length  }}

查找:从对头开始查找,从时间复杂度为 O(n)

插入或删除:进栈与出栈的时间复杂度为 O(1)

二、双端队列(Deque)

1. 什么是 Deque

Deque 在原有队列的基础上扩充了:队头、队尾都可以进队出队,它的数据结构如下:


代码实现:

function Deque() {  let items = []  this.addFirst = function(e) {    items.unshift(e)  }  this.removeFirst = function() {    return items.shift()  }  this.addLast = function(e) {    items.push(e)  }  this.removeLast = function() {    return items.pop()  }  this.isEmpty = function() {    return items.length === 0  }  this.front = function() {    return items[0]  }  this.clear = function() {     items = []   }  this.size = function() {    return items.length  }}

下面看一道经典的双端队列问题?

2. 字节&leetcode151:翻转字符串里的单词

给定一个字符串,逐个翻转字符串中的每个单词。

示例 1:

输入: "the sky is blue"输出: "blue is sky the"

示例 2:

输入: "  hello world!  "输出: "world! hello"解释: 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。

示例 3:

输入: "a good   example"输出: "example good a"解释: 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

说明:

  • 无空格字符构成一个单词。
  • 输入字符串可以在前面或者后面包含多余的空格,但是反转后的字符不能包括。
  • 如果两个单词间有多余的空格,将反转后单词间的空格减少到只含一个。

解题思路:使用双端队列解题

  • 首先去除字符串左右空格
  • 逐个读取字符串中的每个单词,依次放入双端队列的对头
  • 再将队列转换成字符串输出(已空格为分隔符)

画图理解:




代码实现:

var reverseWords = function(s) {    let left = 0    let right = s.length - 1    let queue = []    let word = ''    while (s.charAt(left) === ' ') left ++    while (s.charAt(right) === ' ') right --    while (left <= right) {        let char = s.charAt(left)        if (char === ' ' && word) {            queue.unshift(word)            word = ''        } else if (char !== ' '){            word += char        }        left++    }    queue.unshift(word)    return queue.join(' ')};

更多解法详见 图解字节&leetcode151:翻转字符串里的单词

三、滑动窗口

1. 什么是滑动窗口

这是队列的另一个重要应用

顾名思义,滑动窗口就是一个运行在一个大数组上的子列表,该数组是一个底层元素集合。

假设有数组 [a b c d e f g h ],一个大小为 3 的 滑动窗口在其上滑动,则有:

[a b c]  [b c d]    [c d e]      [d e f]        [e f g]          [f g h]

一般情况下就是使用这个窗口在数组的 合法区间 内进行滑动,同时 动态地 记录一些有用的数据,很多情况下,能够极大地提高算法地效率。

下面看一道经典的滑动窗口问题?

2. 字节&Leetcode3:无重复字符的最长子串

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例 1:

输入: "abcabcbb"输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例 2:

输入: "bbbbb"输出: 1解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例 3:

输入: "pwwkew"输出: 3解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

解题思路: 使用一个数组来维护滑动窗口

遍历字符串,判断字符是否在滑动窗口数组里

  • 不在则 push 进数组
  • 在则删除滑动窗口数组里相同字符及相同字符前的字符,然后将当前字符 push 进数组
  • 然后将 max 更新为当前最长子串的长度

遍历完,返回 max 即可

画图帮助理解一下:


代码实现:

var lengthOfLongestSubstring = function(s) {    let arr = [], max = 0    for(let i = 0; i         let index = arr.indexOf(s[i])        if(index !== -1) {            arr.splice(0, index+1);        }        arr.push(s.charAt(i))        max = Math.max(arr.length, max)     }    return max};

时间复杂度:O(n2), 其中 arr.indexOf() 时间复杂度为 O(n) ,arr.splice(0, index+1) 的时间复杂度也为 O(n)

空间复杂度:O(n)

更多解法详见 字节&Leetcode3:无重复字符的最长子串

最后,来尝试一道leetcode题目吧!

四、leetcode239:滑动窗口最大值问题

给定一个数组 nums 和滑动窗口的大小 k,请找出所有滑动窗口里的最大值。

示例:

输入: nums = [1,3,-1,-3,5,3,6,7], 和 k = 3输出: [3,3,5,5,6,7] 

解释:

滑动窗口的位置                最大值

[1  3  -1] -3  5  3  6  7       3

1 [3  -1  -3] 5  3  6  7       3

1  3 [-1  -3  5] 3  6  7       5

1  3  -1 [-3  5  3] 6  7       5

1  3  -1  -3 [5  3  6] 7       6

1  3  -1  -3  5 [3  6  7]      7

提示:

你可以假设 k 总是有效的,在输入数组不为空的情况下,1 ≤ k ≤ 输入数组的大小。

可以自己尝试解答一下,欢迎将答案提交到 https://github.com/sisterAn/JavaScript-Algorithms/issues/33 ,瓶子君将明日解答?

五、往期精彩

  • 前端进阶算法:常见算法题及完美题解

  • 视频面试超高频在线编程题,搞懂这些足以应对大部分公司

  • 前端进阶算法5:全方位解读前端用到的栈结构(+leetcode刷题)

  • 10 问 10 答,带你快速入门前端算法

  • 前端进阶算法4:链表原来如此简单(+leetcode刷题)

  • 前端进阶算法3:从浏览器缓存淘汰策略和Vue的keep-alive学习LRU算法

  • 瓶子君前端算法集训营第一期开营啦,免费哟

  • 前端进阶算法2:从Chrome  V8源码看JavaScript数组(附赠腾讯面试题)

  • 前端进阶算法1:如何分析、统计算法的执行效率和资源消耗?

六、前端算法集训营第一期免费加入啦

欢迎关注「前端瓶子君」,回复「算法」自动加入,从0到1构建完整的数据结构与算法体系!

在这里,瓶子君不仅介绍算法,还将算法与前端各个领域进行结合,包括浏览器、HTTP、V8、React、Vue源码等。

在这里,你可以每天学习一道大厂算法题(阿里、腾讯、百度、字节等等)或 leetcode,瓶子君都会在第二天解答哟!


⬆️ 扫码关注公众号「前端瓶子君」,回复「算法」即可自动加入 ???

“在看转发”是最大的支持

fifo算法_前端进阶算法6:一看就懂的队列及配套算法题相关推荐

  1. 两个矩阵是否相交的算法_收藏 | 计算机、数学、运筹学等领域的32个重要算法...

    来源:大数据 本文约2500字,建议阅读5分钟. 本文为你分享计算机.数学.运筹学等领域的32个重要算法. [ 导读 ] 奥地利符号计算研究所(Research Institute for Symbo ...

  2. 一层循环时间复杂度_算法的时间与空间复杂度(一看就懂)

    算法(Algorithm)是指用来操作数据.解决程序问题的一组方法.对于同一个问题,使用不同的算法,也许最终得到的结果是一样的,但在过程中消耗的资源和时间却会有很大的区别. 那么我们应该如何去衡量不同 ...

  3. 改进的有效边表算法_优硕微展 | 张和慧:基于邻域保持嵌入算法的间歇过程故障检测研究...

    基于邻域保持嵌入算法的 间歇过程故障检测研究 The Research on batch process fault detection based on Neighborhood Preservin ...

  4. sha256算法_叶胜超:一分钟搞懂哈希以及哈希算法!(15)

    哈希算法 什么是哈希? 哈希的英文:Hash,也可翻译成"散列",也是一种哈希算法的最小单位H,其它单位还有KMGTPE共6个,胜超在前文也讲过,可以用谐音"昆明哥,突破 ...

  5. 大数据基础课11 让你一看就懂的数据挖掘四大经典算法

    上一讲,我们从流程上介绍了数据挖掘,而在整个数据挖掘实施的流程中,数据挖掘算法可能是我们的算法工程师最关注的环节.在常见的数据挖掘过程中,通常会用到什么类型的算法,不同的算法又应对什么样的问题?在实际 ...

  6. 前端面试技巧和注意事项_前端HR的面试套路,你懂几个?

    原标题:前端HR的面试套路,你懂几个? 面试前端工程师对我来说是一件非常有意思的事,因为面试过程很大程度上也是自我提升的过程.经过这几年在行业里的摸索,我总结出了自己的一套很有效的面试前端工程师的方法 ...

  7. java 乱序算法_前端面试(算法篇) - 数组乱序

    一.面试题 问:有一个长度为 100 的数组,如何从中随机挑选 50 个元素,组成一个新的数组? 答:这个...那个...emmmmmm 问:那先不挑 50 个,就挑一个数,知道怎么做吗? 答:这个我 ...

  8. java 最少使用(lru)置换算法_「面试」LRU了解么?看看LinkedHashMap如何实现LRU算法...

    以下内容均是本人原创,希望你看完之后能有更多更深入的了解,欢迎关注➕ 问题:使用Java完成一个简单的LRU算法 什么是LRU算法 LRU(Least Recently Used),也就是最近最少使用 ...

  9. react如何遍历并比较_[前端进阶] 这可能是最通俗易懂的React 渲染原理及性能优化...

    如今的前端,框架横行,出去面试问到框架是常有的事. 我比较常用React, 这里就写了一篇 React 基础原理的内容, 面试基本上也就问这些, 分享给大家. React 是什么 React是一个专注 ...

最新文章

  1. redisTemplate分布式锁演变、redission分布式锁实现!
  2. 校招真题练习011 种花(美团)
  3. atitit.ajax bp dwr 3.的注解方式配置使用流程总结.....
  4. Mysql 内置函数
  5. Winform中对自定义xml配置文件进行Xml节点的添加与删除
  6. MOCTF-Web-文件包含
  7. 【laravel5.4】迁移文件的生成、修改、删除
  8. mallcloud商城基于SpringBoot2.x
  9. springcloud的中文文档地址和中国社区
  10. 如何评价,为何程序员被骂立马就辞职呢?
  11. Kernel, tainted, 被污染的实例
  12. 历年研究生数学建模优秀论文汇总
  13. Graphics.DrawString 方法
  14. easyExcel导出表格及合并单元格
  15. 高通Camx offline Log merge命令
  16. 数论-杨辉三角和二项式定理
  17. Java容器(集合)
  18. c语言如何框出视频或图像中的车辆,[转载]视频图像中的车辆检测跟踪和分类
  19. 华为无线学习笔记--WLAN(无线)实验
  20. hadoop3.3.0版本搭建

热门文章

  1. cdr怎样把一张图片随意变形_CDR钢笔工具怎么抠图?原来使用起来这么简单!
  2. lisp一键室内标注_LISP-标注的自动位置调整
  3. 北京科技大学计算机与通信工程学院计算机科学与技术系导师研究方向,北京科技大学计算机科学与技术系硕士生导师孙昌爱_计算机考研导师...
  4. mysql连接量设置_mysql连接数设置操作方法(Too many connections)
  5. bigdecimal divide四舍五入_BigDecimal 四则运算
  6. python创建员工_python作业员工信息表程序(第四周)
  7. php 零宽断言,正则表达式之零宽断言
  8. pybamm库学习-tutorial
  9. java批量导入和批量删除_MyBatis 实现批量插入和删除中双层循环的写法案例
  10. AntTweakBar with OpenGL