当前位置: 首页 > Web前端 > JavaScript

Javascript刷LeetCode拿offer-滑动窗口

时间:2023-03-27 17:46:24 JavaScript

1.前言《JavaScript刷LeetCode拿offer-双指针技巧》,简单介绍了双指针技术相对于单指针的优势,并结合Easy难度题目,让你深入了解双指针的应用-指针。进入中等难度后,解题的关键在于如何构造双指针,确定指针移动的规则。求解问题的方法可以归纳为以下两大类:滑动窗口算法(SlidingWindowAlgorithm);对数组进行预处理(如:排序、前缀等),然后使用双指针遍历;这两种方法都可以将双循环问题转化为单循环问题,从而有效降低算法的时间复杂度。本篇主要介绍滑动窗口算法和相关题的解题思路,第二类题将在下一篇讲解。滑动窗口算法的具体表现是:左右指针始终保持一个满足条件的窗口值,右指针负责向前遍历。当窗口值不满足条件时,将左指针指向的元素移出窗口,同时左指针向前移动。接下来,我们将结合实际话题来了解如何使用滑动窗口算法。2.567.字符串排列给定两个字符串s1和s2,编写一个函数判断s2是否包含s1的排列。换句话说,第一个字符串的排列之一是第二个字符串的子字符串。这个问题其实可以转化为是否有可能找到满足以下条件的s2字符串的子串:子串的长度等于s1字符串的长度;子串中包含的字符和对应的数字与s1字符串相同;然后结合滑动窗口算法,需要维护一个长度为s1的字符串长度的窗口,窗口中的字符和对应的数字与s1相同。字符数由HashTable维护,Map数据结构可以在JavaScript语言中使用。3.904.果篮在一排树中,第i棵树产生类型为tree[i]的果实。您可以从您选择的任何一棵树开始,然后重复以下步骤:1.将这棵树上的果实放入您的篮子中。如果你做不到,就停下来。2.移动到当前树右侧的下一棵树。如果右边没有树,就停下来。请注意,选择一棵树后,您别无选择:您必须执行第1步,然后第2步,然后返回第1步,然后第2步,依此类推,直到停止。您有两个篮子,每个篮子可以装任意数量的水果,但您希望每个篮子只装一种水果。您可以使用此应用程序收集的水果总量是多少?这道题显然符合滑动窗口算法的特点:维护一个最多有两种水果的窗口。当窗口中出现第三种水果时,需要将窗口左侧的果树移除,以保证当前窗口只包含两种水果。这里可以使用HashTable来记录同种果树最后一次出现的坐标,以优化时间复杂度。最后在移动窗口的过程中,计算出相应的水果总量即可。4.3.最长不重复字符的子串给定一个字符串,请找出最长不重复字符的子串的长度。参考视频:传送门这道题和之前《904. 水果成篮》的解题思路类似:维护一个没有重复字符的窗口;当窗口不满足条件时,从窗口右侧移除字符,以保证再次满足条件时,也可以使用HashTable记录相同字符的最后一个下标,优化时间复杂度;5.713.给定乘积小于K的子数组一个正整数数组nums。求该数组中乘积小于k的连续子数组的个数。这个问题需要维护一个乘积小于k的窗口。与上面的问题相比,这个问题不需要太多技巧来计算有效窗口值。难点在于满足乘积的数组长度正好是不重复子数组的个数。6.845.数组中最长的山我们把数组A中任意一个连续的子数组B满足下列性质的称为“山”:1.B.length>=3;2.存在0B[i+1]>...>B[B.length-1](注:B可以是A的任意子数组,包括整个数组A。)给定一个整数数组A,返回最长“山”的长度。如果没有“山”,则返回0。以这道题为例,感受一下简单解法和滑动窗口算法的差距。简单解的思路:依次将数组中的元素作为“山峰”,如果满足“山峰”的条件,则计算长度。上面代码的时间复杂度是O(n^2)。本题使用滑动窗口算法的难点在于如何确定当前窗口中有效的“山”形:在窗口移动的过程中,需要用到两个变量来记录当前窗口中包含的序列的单调性窗户;在顺序上,如果此时窗口已经包含了降序,则需要将左指针前移,重建“山”;当窗口移动过程中遇到递减序列,如果此时窗口不包含递增序列,同样需要将左指针向前移动,重建“山”;使用滑动窗口算法成功将时间复杂度降低到O(n)。写在最后算法是计算机的基础学科,用JavaScript刷一下也不丢人ε=ε=ε=┏(゜ロツ;)┛。本系列文章将总结算法的三种难度(简单难度、中等难度和困难难度)。简单难度会介绍算法的基础知识和实现,另外两个难度会重点讲解解题思路。如果本文对您有帮助,可以点赞或关注鼓励博主