题目链接:https://leetcode.com/problems/move-zeroes/
题目内容:
Given an array nums
, write a function to move all 0
's to the end of it while maintaining the relative order of the non-zero elements.
For example, given nums = [0, 1, 0, 3, 12]
, after calling your function, nums
should be [1, 3, 12, 0, 0]
.
题目分析:
题目给出的函数参数是vector<int>的,因此使用了vector的api不可避免,msdn上的vector手册在此!这道题其实想了挺久的,因为一看暴力但感觉很low的想法一下子就有了:记录原有vector的长度len1,然后遍历的时候遇到0就删掉,剩下的长度为len2,最后再vector后面补上(len1-len2)个0.一直没动手的原因就是觉得这样无论在时间还是在空间上感觉都很低效。后来想到,多加一个指针或者游标就可以了啊,让它记录不为0的数的位置,另一个游标一直往前遍历,最后再补上0,这里的补上只要修改值就可以。原来的和优化后的代码如下,其中,注释的为原来的代码。注意,原来的代码中每删掉(erase操作)一个元素,整个vector的长度减1,相应的当前游标应该回滚到上一个,因为在循环体内结束一次循环,即”}“之前会修改游标的值(做”++“操作)
void moveZeroes(vector<int>& nums) {
/**
* cost 20ms
int size = nums.size();
for(vector<int>::iterator cur = nums.begin(); cur != nums.end(); cur++) {
if(*cur == 0) {
nums.erase(cur);
cur--;
} else
continue;
}
int cursize = nums.size();
for(int count = 0; count < size-cursize; count++)
nums.push_back(0);
*/
int size = nums.size();
vector<int>::iterator nonZero = nums.begin();
vector<int>::iterator current = nonZero;
vector<int>::iterator end = nums.end();
for(; current != nums.end(); current++) {
if(*current != 0) {
*nonZero = *current;
nonZero++;
}
}
for(; nonZero != end; nonZero++)
*nonZero = 0;
}