引用:我们之前学过快排,首先用三元取中,找(key),然后就用到了双指针的方法来进行交换排序,那我们今天要讲的双指针其实大同小异,无非在数组中就变成了下标。
题一:
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
题一思路:
current起到遍历作用,从左向右,起始位置在第一个元素,即下标0;
desteration是指最后一个非0元素,起始位置在第一个元素前一个,即下表-1;
当current当前是非0元素,即desteration++,然后让current与desteration所指向的原素进行交换,current++
当current当前是0元素,即current++;
当current遍历完,则结束循环,输出结果!
思路图如下:
题一思路代码:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int current=0;
int desteration=-1;
int size=nums.size();
while(current!=size)
{
if(nums[current]!=0)
{
desteration++;
swap(nums[current],nums[desteration]);
current++;
}
else
{
current++;
}
}
}
};
题二:
给你一个长度固定的整数数组 arr
,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。
注意:请不要在超过该数组长度的位置写入元素。请对输入的数组 就地进行上述修改,不要从函数返回任何东西。
题二思路:
我们如果从前往后进行操作的话,会出现desteration在current之后,所以我们要从后往前操作,故我们要找出最后一个current的位置,desteration为最后一个位置刚好为最后一个元素。
但是如果最后一个current指向的元素为0,那desteration会超出数组范围,也就是越界。
故这作为一种特殊情况处理。如图:
常规:
一,找最后一个current步骤:1,判断当前current的值。2,让desteration进行向后移动一步或二步。3,判断desteration是否到最后。4,current++;
(特殊情况)n-1=0,current--,desteration-=2;
二,进行逆"复写"。
题二思路代码:
class Solution {
public:
void duplicateZeros(vector<int>& arr) {
int desteration=-1;
int current=0;
while(current<arr.size())
{
if(arr[current]!=0)
{
desteration++;
}
else{
desteration+=2;
}
if(desteration>=arr.size()-1)
{
break;
}
current++;
}
if(desteration==arr.size())
{
current--;
arr[arr.size()-1]=0;
desteration-=2;
}
//逆复写
while(current>=0)
{
if(arr[current]!=0)
{
arr[desteration--]=arr[current--];
}
else{
arr[desteration--]=0;
arr[desteration--]=0;
current--;
}
}
}
};