-
题目
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
提示:- 1 <= nums.length <= 104
- -231 <= nums[i] <= 231 - 1
示例一:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例二
输入: nums = [0]
输出: [0]
-
思路
- 第一种,忽略题干的“请注意”,使用辅助vector来解题:
- 先把一个size为
nums.size()
,元素初始化都为0,名为ans
的vector - 然后遍历
nums
,把不为0的元素赋给ans
- 最后,让把
ans
赋给nums
- 先把一个size为
- 第二种,在原始数组上二次遍历
- 定义一个变量
j
记录非零元素个数 - 第一次遍历,每遇到一个非零元素就往数组左边挪动,遍历结束,
j
记录最后一个非零元素的后一个元素的下标 - 第二次遍历,从
j
开始遍历数组,从j
到数组最后一个元素都置零
- 定义一个变量
- 第三种,在原始数组上一次遍历:
- 和第二种相似,但是在第一次遍历里操作不同,第二种的第一次遍历是将非0元素左挪,本方法的一次遍历是把非零元素和
nums[j]
进行交换; - 本方法类似快速排序,中间点是0,当不为0时(考虑负数)时把元素放到中间点的左边,0放中间点的右边
- 和第二种相似,但是在第一次遍历里操作不同,第二种的第一次遍历是将非0元素左挪,本方法的一次遍历是把非零元素和
- 第一种,忽略题干的“请注意”,使用辅助vector来解题:
-
代码
class Solution {
public:
void moveZeroes(vector<int>& nums) {
//第一种,不符合题目要求
if(nums.empty())
return ;
int zero = 0 , rnum = 0 , length = nums.size();
vector<int> ans(length,0);
for(int i=0;i<length;i++){
if(nums[i]==0){
zero++;
continue;
}
else{
ans[rnum] = nums[i];
rnum++;
}
}
nums = ans;
return ;
//第二种,二次遍历
if(nums.empty())
return ;
int j = 0;
for(int i = 0;i<nums.size();i++){
if(nums[i]!=0){
nums[j++]=nums[i];
}
}
for(;j<nums.size();j++)
nums[j]=0;
//第三种,一次遍历,类似快排
if(nums.empty())
return ;
int j = 0;
for(int i = 0;i<nums.size();i++){
if(nums[i]!=0)
swap(nums[j++],nums[i]);
}
}
};