一、题目
二、分析
题目让我们不能复制,只能在数组中交换移动。那么数组中的移动,比较方便的是前后两个元素交换,并且非零元素相对位置不变,那就考虑0和它后面的非0元素进行交换,进一步思考,除了单个0移动,还可以将多个0 聚集成一个串,通过两个指针分别指向串的开头和结尾,然后就可以将这个串作为一个整体跟后面的非0元素交换,这样可以减少交换次数。
所以,解题的总的思想:单个的0依次跟后面的元素交换,向后移位,当多个0汇合之后它们作为一个整体一起后移
三、代码
class Solution {
public:
void moveZeroes(vector<int>& nums) {
if(nums.size()==0 || nums.size()==1) return;
/*
设置前后两个指针:front和back,(默认数组下标小则为前,数组下标大则为后)
1. 首先back向后遍历,当出现一个0时,让front指向当前位置
2. back继续向后遍历,如果下一个不是0,则交换,否则,back继续向后,
直到出现不是0的元素,将front和back位置交换,(这时出现了一个0串,将0串开头与串后面出现的一个元素交换就等于把这个元素移到了0串的前边,而0串后移了一位)并移动front位置使其始终指向0串的开头
3.back继续向后重复上一步,直到结束
*/
int front=-1; //-1说明还没有出现0,没有指向的位置
int back=0;
int changenum;
for(;back<nums.size();back++){
if(nums[back]!=0){
if(front>=0){
changenum=nums[back];
nums[back]=nums[front];
nums[front]=changenum;
front++; //交换之后front就指向了非0元素,于是往后一步就又指向了0串的开头
}
}else{
if(front<0) front=back;
}
}
}
};