双指针分为同向双指针和反向双指针
同向双指针
其中 [0,i) 的数据代表处理好的数据,[i,j)中的数据是那些处理过但不需要的数据,[j,array.length) 区间的数据为接下来待处理的数据。这三个区间的开闭要根据题目要求定义,但是要保持一致(不能让一个端点值在一个区间的右边和另一个区间的左边都闭合)。
用此方法处理过的数组,处理好的数据的相对位置会保持一致 ,即[1,2,0,3,0,8] 将0移至数组尾部,使用此方法,结果只可能是[1,2,3,8,0,0]而不可能是[8,3,2,1,0,0] 或者其他
通用解题步骤
1. 初始化两个指针 i, j ,通常是两者都取0 或者两者都取 n
2. while(j < arr.length)
- 如果需要array[j],通过将array[j]赋值给array[i],即 array[i] = array[j],并且将 i 向前移,让其准备好下一个将要被赋值的位置
- 否则跳过j,如果不满足条件,我们不必移动 i
反向双指针
其中 [0,i) 和 [j,array.length) 区间的数据的数据均代表处理好的数据,[i,j)中的数据待处理。用此方法处理过的数组不会保留原来元素的位置
通用解题步骤
1. 初始化两个指针 i = 0 , j = array.length - 1
2. while( i <= j )
- 根据题意决定 array[i] 和 array[j] 的值(有可能是交换值,有可能是取较小的值等等)
- 每次至少会有一个指针移动
示例:力扣26
给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。
由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。
var removeDuplicates = function(nums) {
var left = 0;
var right = 0;
var len = nums.length;
while(right < nums.length){
// 本题的突破口是重复元素的两项一定是相邻的
if(nums[left] === nums[right]){
right++
}else if(nums[left] != nums[right]){
nums[left+1] = nums[right]
left++;
right++;
}
}
return left+1
};