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].
Note:
You must do this in-place without making a copy of the array.
Minimize the total number of operations.
方法1:从后向前遍历数组,当遇到0时,将已经遍历过非0的数字逐个向前移动,这种方法耗时较多。
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int last = nums.size()-1;
for(;last>=0;last--){
if(nums[last]==0){
int i;
for(i = last;nums[i+1]!=0&&i+1<nums.size();i++)
nums[i]=nums[i+1];
nums[i]=0;
}
}
}
};
方法2:从前向后正序遍历数组,设置两个指针i与j,i初始值指向第一个0元素,j初始值指向第一个非0的元素,用指针j进行遍历数组,当指针j所指向的数字为非0时,那么将该数字赋值到指针i的位置,然后进行i++。
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int i = 0;
while(nums[i]!=0)
i++;
int j = i+1;
while(nums[j]==0)
j++;
while(j<nums.size()){
if(nums[j]!=0)
nums[i++]=nums[j++];
else
j++;
}
while(i<nums.size())
nums[i++]=0;
}
};
方法2的方法属于sub-optimal,因为当一个数组中0元素很多时,最后需要重新对这些0元素重新写入0,耗费时间。
方法3:只对非0元素的数字进行移动,最优化的方法。这种方法可以保持i之前的元素均为非0,i与j之间的元素均为0。
class Solution {
public:
void moveZeroes(vector<int>& nums) {
for(int i = 0,j= 0;j<nums.size();j++){
if(nums[j]!=0)
swap(nums[i++],nums[j]);
}
}
};