算法——数组专辑(一):数组的双指针运用

前言:
处理数组和链表相关问题,双指针经常用到,双指针主要分类:左右指针和快慢指针。
1.左右指针:两个指针相向而行或者相背而行
2.快慢指针:两个指针同向而行,一块一慢
注意:数组并没有真正意义上的指针,但是可以把索引当做数组中的指针。

快慢指针

一:数组去重
数组问题中常见的快慢指针技巧:原地修改数组
力扣26题: 删除有序数组中的重复项
算法——数组专辑(一):数组的双指针运用_第1张图片
原地修改:只能在原数组上操作,返回一个长度,通过返回的长度和原始数组得到去重后的元素有哪些

解题思路:
使用快慢指针技巧,慢指针slow走在后面,快指针在前面探路,找到一个不重复的元素就让slow前进一步,并赋值给slow。(因为要保证第一个或已经修改过的元素不被覆盖,所以要先走一步)
保证了nums[0…slow]都是无重复的结果,当指针遍历完整个数组之后,nums[0…slow]就是整个数组去重后的结果。

核心算法:

while(fast

二:根据某些元素进行数组去重
看力扣27题移除元素
算法——数组专辑(一):数组的双指针运用_第2张图片
给的函数规范
int removeElement(int[] nums,int val);

解题思路:
和上面那道题基本一样,注意小细节的改变

while(fast

第一处①:
先赋值还是先后移,取决于我们是否需要一上来就修改值,如果是根据去重val值,我们必须先判断数组里的值是否为要去val值(所以肯定不能先后移,这样会漏值)。

第二处②:
先赋值后+±—保证了数组[0-slow-1]是不包含val,数组的长度为slow
先++后赋值----保证了数组[o-slow]无重复结果,数组长度slow+1

注意:我们要认清返回数组的长度是多少算法——数组专辑(一):数组的双指针运用_第3张图片

左右指针

最经典的用法应用于二分查找,一左一右指针相向而行
(后面会更新二分查找)。
这里列举核心算法,展示最基础的二分查找。

int left =0,right=nums.length-1;左右指针
while(left<=right){
int mid =(right+left)/2;
if(nums[mid]==target)
return mid;
else if (nums[mid]target)
right=mid-1;
}

例题:力扣167题 两数之和 II - 输入有序数组
算法——数组专辑(一):数组的双指针运用_第4张图片
我们只需注意一点,如果数组是有序的,我们首先要考虑双指针技巧。
核心题解如下:
算法——数组专辑(一):数组的双指针运用_第5张图片
这里面有一个细节需要注意:
right设置为数组长度-1,同时在while循环里我们用的是<,这样while的终止条件就是left==right。

再来一道面试题,面科大讯飞时出的一道:344反转字符串
算法——数组专辑(一):数组的双指针运用_第6张图片
核心代码
算法——数组专辑(一):数组的双指针运用_第7张图片
下面提升一点难度
力扣第五题最长回文子串
算法——数组专辑(一):数组的双指针运用_第8张图片
这道题我们需要注意的是:
1.回文串的长度可能是奇数或者偶数。
2.左右指针的运用并不是收缩,而是扩展。
我们可以先实现一个函数去寻找以中心为基准向两端扩展的最长回文串。
算法——数组专辑(一):数组的双指针运用_第9张图片
那么我们大致的解题思路为:

找到s[i]为中心的回文串(奇数)
找到s[i]和s[i+1]为中心的回文串(偶数)
更新答案

代码实现如下:
算法——数组专辑(一):数组的双指针运用_第10张图片

你可能感兴趣的:(数据结构和算法,算法,leetcode,职场和发展)