题目:
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/move-zeroes
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
额外空间:
虽然要求不能用额外数组,不妨想想有额外数组时能怎么解决这题。我们可以建立一个额外的空数组,并从后遍历原数组。当遍历到非零元素时,将此元素放入空数组前端。最后在后面填零。
交换:
因为要在原数组上操作且要保持原顺序,所以我们先试试交换的方法。根据提示,先用一个变量curIndx遍历数组,再用一个变量curNoneZero储存当前不是0的元素的位置。两个变量一开始都指向0,遍历时每当nums【curIndx】不是0时,和nums【curNoneZero】互换并增加curNoneZero。
代码:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int curIndx = 0;
int curNonZero = 0;
int n = nums.size();
while (curIndx < n)
{
if (nums[curIndx] != 0)
{
swap(nums[curIndx], nums[curNonZero]);
curNonZero ++;
}
curIndx ++;
}
}
};
时间复杂度:O(n)
空间复杂度:O(1)
覆盖:
我们可以简化需要多余空间的解法:直接在原数组上进行覆盖。用一个变量indx记录当前的下标。遍历原数组,如果当前遍历到的值不是0,那么设nums【indx】为当前遍历到的值并递增indx。这样遍历完后,indx的值就是非零元素的数量。最后在剩余位置覆盖零。
代码:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int curindx = 0;
int n = nums.size();
for (int num:nums)
{
if (num != 0)
{
nums[curindx] = num;
curindx ++;
}
}
for (int i = curindx; i < n; i++)
{
nums[i] = 0;
}
}
};
时间复杂度: O(n)
空间复杂度: O(1)
参考:
https://leetcode-cn.com/problems/move-zeroes/
https://leetcode-cn.com/problems/move-zeroes/solution/yi-dong-ling-by-leetcode-solution/