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

JavaScript刷LeetCode,拿offer-双指针技术(上)_1

时间:2023-03-27 00:24:51 JavaScript

1.前言一般情况下,遍历数组(或字符串)的操作都是使用单指针,从前到后或从后到后依次访问数组(或字符)字符串中的前面元素)。对于以下情况,只使用单指针处理会增加时间复杂度和空间复杂度:例如:求两个数,使其和等于目标数,使用单指针处理,需要嵌套循环,使时间复杂度增加到O(n^2);又如:翻转数组,使用单指针处理需要额外的内存空间,使得空间复杂度增加到O(n);上面的方案可以用双指针技术优化解决方案:第一个例子:可以先对数组进行排序和预处理,然后创建和遍历指向中间的指针。遍历的时间复杂度为O(n)。整体时间复杂度主要取决于排序算法,通常为O(nlogn);第二列:一个指针负责遍历,另一个指针负责交换元素,这样空间复杂度为O(1);双指针没有复杂的定义,概括起来主要处理两类问题:嵌套循环转化为单循环问题;通过指针记录状态,从而优化空间复杂度;下面的实战分析,让你感受双指针的威力。2.167.两个数之和II-输入排序数组给定一个已按升序排序的排序数组,找到两个数,使得它们的和等于目标数。该函数应该返回两个索引值index1和index2,其中index1必须小于index2。本题使用单指针的方法只能通过嵌套循环枚举所有两个数的和来求解,时间复杂度为O(n^2)。正好这道题的数组已经是有序数组了,所以直接创建前后指针:如果两个数都大于target,则尾指针向前移动;如果两个数之和小于目标值,则头指针向后移动;上面的代码使用双指针技术成功地将时间复杂度降低到O(n)。3.344.ReverseString编写一个函数,其功能是反转输入的字符串。输入字符串以char[]字符数组的形式给出。本题采用单指针方式,需要额外创建一个数组来保存翻转后的元素,空间复杂度为O(n)。使用双指针技术,可以在遍历过程中同时完成交换元素的操作,时间复杂度降低为O(1):,141.环形链表给定一个链表,判断是否存在链表中的一个环。为了表示给定列表中的循环,我们使用整数pos来表示列表中尾部连接的位置(索引从0开始)。如果pos为-1,则列表中没有循环。在链表的数据结构中,使用上面提到的前后指针不一定有效(比如单向链表)。在这种情况下,双指针的表达形式是:快指针和慢指针。快慢指针是指:设置两个指针的前进方向相同但速度不同。本题设置一次移动一个单位的慢指针和一次移动两个单位的快指针,那么他们一定会在圆环中相遇:参考视频:传送门同类型题还有:[26.删除排序数组重复]五、125.验证回文给定一个字符串,验证是否为回文,只考虑字母和数字,忽略字母大小写。解释:在这道题中,我们定义一个空字符串作为一个有效的回文。回文串问题是双指针的经典应用,也是面试题中的常客。6.27.移除元素给定一个数组nums和一个值val,你需要原地移除所有值等于val的元素,并返回被移除数组的新长度。不要使用额外的数组空间,您必须就地修改输入数组并使用O(1)额外空间进行修改。元素的顺序可以改变。您不需要考虑数组中超出新长度的元素。显而易见的解决方案是使用while+splice,但是splice操作方法非常耗时。每个元素被删除后,数组中的元素需要重新排列。同样有副作用的还有unshift和shift操作方法。(具体请查看V8源码)相比之下,pop和push是非常快的操作方式。这里可以使用双指针+pop的操作方式进一步优化时间复杂度:写在最后滑动,一点都不丢人ε=ε=ε=┏(゜ロツ;)┛。本系列文章将总结算法的三种难度(简单难度、中等难度和困难难度)。简单难度会介绍算法的基础知识和实现,另外两个难度会重点讲解解题思路。如果本文对您有帮助,可以点赞或关注,鼓励博主。