「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」
双指针算法
介绍
双指针算法,依名知意。就是会出现两个指针,但是是在什么情况下出现?又是是如何作用?该如何执行的呢?
1.应用场景
双指针算法的应用场景一般出现在 有序数组 或者 链表,且需要进行遍历的过程。所以我们只要遇到这两种场景,就要立刻第一反应 可能会用到双指针算法。
2.双指针算法分类
双指针算法分类有两种,一种是 快慢指针,一种是 对撞指针。这两种经典且应用场景广泛的指针!
-
快慢指针
两个指针 指向同一方向,一个指针在前面,一个指针在后边,根据相关的条件,快指针走得快,慢指针走的慢,直到满足条件或者快指针指向null 或者是 走到结尾 。使用场景:
-
对撞指针 两个指针 分别指向最左端和最右端,然后找到目标所在的值或下标,动态的移动左右两侧指针,来以此慢慢靠近我们所需的目标值或下标。使用场景:
题目
-
删除有序数组中的重复项-26
给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成
-
环形链表-141
给你一个链表的头节点 head ,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。如果链表中存在环,则返回 true 。 否则,返回 false
-
两数之和 II - 输入有序数组-167
给定一个已按照 非递减顺序排列 的整数数组 numbers ,请你从数组中找出两个数满足相加之和等于目标数 target 。函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ,所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素
-
验证回文串-125
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写
代码
-
-
有序数组的去重
// 快慢指针 const removeDuplicates = (nums) => { let i = 0 // 慢指针 for (let j = 1; j < nums.length; j++) { if (nums[j] != nums[i]) { i++ nums[i] = nums[j] } } return i + 1 }// 常规方式 const removeDuplicates = (nums) => { for (let i = 0; i < nums.length; ) { if (nums.indexOf(nums[i]) !== i) { nums.splice(i, 1) } else { i++ } } return nums // 这里返回的是去重后的数组 // return nums.length // 这里返回的是去重后的数组长度 } -
链表是否有环 141题
const hasCycle = (head) => { if (head == null || head.next == null) { return false } var slow = head.next var fast = head.next.next while (slow !== fast) { if (fast == null || fast.next == null) { return false } slow = slow.next fast = fast.next.next } return true }
-
-
对撞指针
-
有序数组的两个数之和 167题
const twoSum = (numbers, target) => { const numbersLength = numbers.length let left = 0 let right = numbersLength - 1 while (left < right) { const ans = numbers[left] + numbers[right] if (ans === target) return [left + 1, right + 1] if (ans < target) left++ else right-- } return [-1, -1] } -
验证是否是回文串 125题
const isPalindrome = (s) => { // const str = s.replace(/[^\w]/g, '').replace(/_/g, '').toLowerCase() const str = s.replace(/[^a-zA-Z0-9]/g, '').toLocaleLowerCase() const strArr = str.split('') let i = 0 let j = strArr.length - 1 while (i < j) { if (strArr[i] !== strArr[j]) { return false } i++ j-- } return true }
-
总结
双指针算法 作为 数据结构的 基础算法之一,学习它对于帮助打开后续的其他数据结构算法,提升思路的灵活度还是很重要的!