快慢指针/同向指针
- [0,i)的数据代表处理好的数据
- [i,j)的数据是那些处理过但不需要的数据
- [j,array.length)区间的数据为接下来待处理的数据。
以上三个区间的开和闭需要根据题目要求定义,但是要保持一致。
用此方法处理过的数组,处理好的数据相对位置会保持一致。
例如:
[1,2,0,3,0,8]move zeros to the end->[1,2,3,8,0,0],not[8,2,3,1,0,0]or others
通用步骤:
- Initialize two pointers i and j, usually both equal to 0
- while j < array.length
if we need array[j],then we keep it by assigning array[i]=array[j],and move i forward, make it ready at the next position
otherwise skip it. We do not need to move i since its spot is not fulfilled
举例:
26. 删除有序数组中的重复项
题解:
//leetcode 26.Remove Duplicates From Sorted Array 快慢指针
//图灵星球题解
public int removeDuplicates(int[] arr)
{
//initialization
int i = 0, j = 0;
while (j < arr.size())
{
//if not duplicate, keep it, otherwise skip it
if (i == 0 || arr[j] != arr[i - 1]) arr[i++] = arr[j++];
else j++;
}
//i is now at the length of the new array,[0,i) is what we want
return i;
}
//labuladong题解
int removeDuplicates(int[] nums)
{
if (nums.size() == 0) return 0;
int slow = 0, fast = 0;
while (fast < nums.size())
{
if (nums[fast] != nums[slow])
{
slow++;
//维护nums[0..slow]无重复
nums[slow] = nums[fast];
}
fast++;
}
//数组长度为索引+1
return slow + 1;
}
左右指针/反向指针
[0,i)和(j,array.length)内的数据均为处理好的数据,[i,j]中的数据待处理。
用此方法处理过的数组不会保留原来元素的相对位置
通用步骤:
- Initialize two pointers i=0,j=array.length -1
- while i<=j:
Decide what you should do based on the value of array[i] and array[j]
Move at least one pointer forward in its direction
举例:
344. 反转字符串
题解:
public char[] reverseString(char[] str)
{
//initialize
int i = 0, j = str.length - 1;
//two pointers opposite direction
while (i < j)
{
//swap str[i] and str[j]
char tmp = str[i];
str[i] = str[j];
str[j] = tmp;
i++;
j--;
}
return str;
}
//leetcode官方题解
class Solution {
public:
void reverseString(vector<char>& s) {
int n = s.size();
for (int left = 0, right = n - 1; left < right; ++left, --right) {
swap(s[left], s[right]);
}
}
};