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元素填补到原先的数组中。之后将没填补的位置全都赋成0。
class Solution {
public:
// 时间复杂度O(n)
// 空间复杂度O(n) 不是一个原地算法,使用辅助空间
void moveZeroes(vector<int> &nums)
{
vector<int> nonZeroElements;
for (int i = 0; i < nums.size(); i++)
if (nums[i]) nonZeroElements.push_back(nums[i]);
for (int i = 0; i < nonZeroElements.size(); i++)
nums[i] = nonZeroElements[i];
for (int i = nonZeroElements.size(); i < nums.size(); i++)
nums[i] = 0;
}
};
思路2(优化,不使用辅助空间):
定义区间[0…k)存放非0元素,初始k=0,即区间[0…0)不存在任何元素
class Solution {
public:
// 时间复杂度O(n)
// 空间复杂度O(1)
void moveZeroes(vector<int> &nums)
{
int k = 0; // nums中,[0...k)的元素均为非0元素
// 遍历到第i个元素后,保证[0...i]中所有非0元素都按照顺序排列在[0...k)中
for (int i = 0; i < nums.size(); i++)
if (nums[i])
nums[k++] = nums[i];
for (int i = k; i < nums.size(); i++)
nums[i] = 0;
}
};
思路3(继续优化,不再单独赋0)
class Solution {
public:
// 时间复杂度O(n)
// 空间复杂度O(1)
void moveZeroes(vector<int> &nums)
{
int k = 0; // nums中,[0...k)的元素均为非0元素
// 遍历到第i个元素后,保证[0...i]中所有非0元素都按照顺序排列在[0...k)中,
// 同时[k..i]为0
for (int i = 0; i < nums.size(); i++)
if (nums[i])
swap(nums[k++], nums[i]);
}
};
思路4(继续优化,极端情况所有的元素都是非0,按照上述实现,所有的元素都会和自身交换)
class Solution {
public:
// 时间复杂度O(n)
// 空间复杂度O(1)
void moveZeroes(vector<int> &nums)
{
int k = 0; // nums中,[0...k)的元素均为非0元素
// 遍历到第i个元素后,保证[0...i]中所有非0元素都按照顺序排列在[0...k)中,
// 同时[k..i]为0
for (int i = 0; i < nums.size(); i++)
if (nums[i])
if (k != i)
swap(nums[k++], nums[i]);
else
k++;
}
};