题目描述:
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
方法1:
主要思路:
(1)首先找出数组中第一个不为0的元素的位置;
(2)从该位置开始,将不为零的值逐个向前赋值,赋值的位置从count=0开始,并逐渐自增count;
(3)当遍历完数组,将所有的非零元素移动到前面之后,将count后面的元素全部置为0;
class Solution {
public:
void moveZeroes(vector<int>& nums) {
//处理特殊情形
if(nums.size()<2)
return;
int count=0;
int i=0;
//处理一开始就为0的情形
for(;i<nums.size()&&!nums[i];++i);
if(i==nums.size())
return;
//处理非零元素前移
for(;i<nums.size();++i){
if(nums[i]){
nums[count++]=nums[i];
}
}
//将包含全部非零元素的子数组后面的元素前部置为0
while(count<nums.size()){
nums[count++]=0;
}
return;
}
};
方法2:
和方法1基本一样,只是删除了判断一开始的元素为0的情形,同样可以直接通过,简化了代码,但计算量没变换
class Solution {
public:
void moveZeroes(vector<int>& nums) {
if(nums.size()<2)
return;
int count=0;
int i=0;
for(;i<nums.size();++i){
if(nums[i]){
nums[count++]=nums[i];
}
}
while(count<nums.size()){
nums[count++]=0;
}
return;
}
};
方法3:
主要思路:
在方法2的基础上,将单独的处理后面的赋值零的操作,放入到了循环遍历中,增加了i>lable这个判断条件,保证不会把自己赋值为0,进而直接在这里将nums[ i ] 赋值为0,减少后面的操作,简化代码;
class Solution {
public:
void moveZeroes(vector<int>& nums) {
if(nums.size()<2)
return;
int lable=0;
for(int i=0;i<nums.size();++i){
if(nums[i]){
if(i>lable){
nums[lable]=nums[i];
nums[i]=0;
}
++lable;
}
}
return;
}
};