例如:
Input: [0,1,0,3,12]
Output: [1,3,12,0,0]
要求:
1. 就地移动,不借助额外空间。
2. 最小化操作次数。
难度:【easy】
思路:遍历一次数组,将不为0的元素向前移动。使用双指针解决。
注意事项:非0元素的相对顺序不能改变。
时间复杂度:O(n)
空间复杂度:O(1)
方法1:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
// j 指向第一个为0的元素
int j = 0;
// i 遍历nums数组
// 当i指向非0元素时,且j != i 时,将i指向的元素向前移动;
// j指向的0元素向后移动,也就是移动到i的位置
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] != 0) {
if (i != j) {
nums[j] = nums[i];
nums[i] = 0;
}
++j;
}
}
}
};
方法2:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
// j指向当前可以放入非0元素的位置
int j = 0;
// 先将所有非0元素向前码放
for (int i = 0; i < nums.size(); ++i) {
if (nums[i] != 0) {
nums[j++] = nums[i];
}
}
// 再将后面的位置全部补0
for (; j < nums.size(); ++j) {
nums[j] = 0;
}
}
};
两种方法对比:
发现第二种方法效率略高。
方法 | Runtime | Memory |
方法1 | 16ms | 9.5 MB |
方法2 | 12 ms | 9.6 MB |