一、双指针-数组 相关题型与常用思路
1、单个数组
(1)原地移除元素类
如推荐习题中的(1)、(2)、(3),都属于此类。引入双指针 pre、last ,用 pre 指针表明数组的最后位置;用 last 指针结合 for 遍历数组,去寻找不符合题意的元素,将其插入有效数组中,也就是 pre 位置,从而达到原地处理的要求。
以题(2)为例:
class Solution {public int removeDuplicates(int[] nums) {//慢指针:指向最终数组的最后元素int low = 0;//在比较中将第一个元素视为不同元素int res = 1;//快指针从1开始,因为要默认保存第一个元素,后面的元素再进行比较for(int fast = 1; fast < nums.length; fast++){//若重合,则过滤不保存;除非不重合,则保存该元素if(nums[fast] != nums[low]){res++;low++;nums[low] = nums[fast];}}return res;}
}
(2)特殊规则处理元素
如推荐习题中的(5),若要实现时间复杂度为 O(n),必然是使用双指针的。用双指针从数组的两侧往中间位置移动,直到遍历完所有元素。
class Solution {public int[] sortedSquares(int[] nums) {int len = nums.length;int[] res = new int[len];int i,j,x;i = 0;j = len - 1;x = len - 1;//从两端往中间依次判定while(i <= j){if(Math.abs(nums[i]) >= Math.abs(nums[j])){res[x] = nums[i] * nums[i];i++;}else{res[x] = nums[j] * nums[j];j--;}x--;}return res;}
}
(3)滑动窗口--待补充
2、两个数组
一定规则下,比较两数组之间的关系,大多是相等关系。
如推荐习题中的(4),若要实现时间复杂度为 O(m+n),必然是使用双指针的。结合提意,此题需要从尾部开始遍历,遇见特殊字符时,做好标记,以便直接跳过后续的字符。
class Solution {public boolean backspaceCompare(String s, String t) {int sLen = s.length();int tLen = t.length();int p1 = sLen - 1;int p2 = tLen - 1;int skipS = 0;int skipT = 0;//倒序处理字符串while(p1 >= 0 || p2 >= 0){while(p1 >= 0){if(s.charAt(p1) == '#'){ // 为退格符,则增加退格符数量skipS++;p1--;}else{ if(skipS > 0){ // 为字母,且退格符数量为正数,则减少退格符数量 skipS--;p1--;}else{ // 为字母,且退格符数量为0,则退出当轮循环break;}}}while(p2 >= 0){if(t.charAt(p2) == '#'){ // 为退格符,则增加更退格符数量skipT++;p2--;}else{ if(skipT > 0){ // 为字母,且退格符数量为正数,则减少退格符数量 skipT--;p2--;}else{ // 为字母,且退格符数量为0,则退出当轮循环break;}}}if(p1 >= 0 && p2 >= 0){ //对比两个字符串中有效字符是否相同if(s.charAt(p1) == t.charAt(p2)){p1--;p2--;}else{return false;} }else if(p1 < 0 && p2 >= 0 || p1 >= 0 && p2 < 0){ //或有一方已为空,而另一方不为空【若不处理会导致死循环!!】return false;}}if(p1 > 0 || p2 > 0){ //若经过上述比较,仍然存在至少一方不为空,则表明两字符不相同return false;}return true;}
}
二、推荐习题
(1)原地 移除元素
27.移除元素
给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素。元素的顺序可能发生改变。然后返回 nums
中与 val
不同的元素的数量。
假设 nums
中不等于 val
的元素数量为 k
,要通过此题,您需要执行以下操作:
- 更改
nums
数组,使nums
的前k
个元素包含不等于val
的元素。nums
的其余元素和nums
的大小并不重要。 - 返回
k
。
(2)原地 删除有序数组的重复项
26.删除排序数组中的重复项
给你一个 非严格递增排列 的数组 nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums
中唯一元素的个数。
考虑 nums
的唯一元素的数量为 k
,你需要做以下事情确保你的题解可以被通过:
- 更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。 - 返回
k
。
(3)原地 移除目标值到数组末尾
283.移动零
(4)比较有效字符串
844.比较含退格的字符串
(5)对有序数组元素的平方值,形成新有序数组
977.有序数组的平方