一、双指针-数组 相关题型与常用思路
1、单个数组
(1)原地移除元素类
如推荐习题中的(1)、(2)、(3),都属于此类。引入双指针 pre、last ,用 pre 指针表明数组的最后位置;用 last 指针结合 for 遍历数组,去寻找不符合题意的元素,将其插入有效数组中,也就是 pre 位置,从而达到原地处理的要求。
以题(2)为例:
java
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),必然是使用双指针的。用双指针从数组的两侧往中间位置移动,直到遍历完所有元素。
java
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),必然是使用双指针的。结合提意,此题需要从尾部开始遍历,遇见特殊字符时,做好标记,以便直接跳过后续的字符。
java
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)原地 移除元素
给你一个数组 nums
和一个值 val
,你需要 原地 移除所有数值等于 val
的元素。元素的顺序可能发生改变。然后返回 nums
中与 val
不同的元素的数量。
假设 nums
中不等于 val
的元素数量为 k
,要通过此题,您需要执行以下操作:
- 更改
nums
数组,使nums
的前k
个元素包含不等于val
的元素。nums
的其余元素和nums
的大小并不重要。 - 返回
k
。
(2)原地 删除有序数组的重复项
给你一个 非严格递增排列 的数组 nums
,请你**原地** 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums
中唯一元素的个数。
考虑 nums
的唯一元素的数量为 k
,你需要做以下事情确保你的题解可以被通过:
- 更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。 - 返回
k
。
(3)原地 移除目标值到数组末尾

(4)比较有效字符串

(5)对有序数组元素的平方值,形成新有序数组
