描述
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/move-zeroes/
求解
class Solution {
public:
// 第一版,将所有非0元素挪到最前端,后面的位置全部赋值0元素
void moveZeroes_1e(vector<int> &nums) {
int k = 0; // [0...k)存放非0元素
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;
}
}
// 第二版,遍历元素,依次将非0元素与前面的0元素交换(实际上这个实现里面可能存在两个相等的非0元素交换)
void moveZeroes_2e(vector<int> &nums) {
int k = 0; // [0...k)存放非0元素
for (int i = 0; i < nums.size(); ++i) {
if (nums[i]) {
std::swap(nums[i], nums[k++]);
}
}
}
// 第二版优化,非0元素只跟0元素交换(当然,增加了一个判断,效率是不是真的有提高不好说,跟实际的数据构成有关系)
void moveZeroes(vector<int> &nums) {
int k = 0; // [0...k)存放非0元素
for (int i = 0; i < nums.size(); ++i) {
if (nums[i]) {
if (i != k) {
std::swap(nums[i], nums[k++]);
} else {
++k; // 很重要,i == k的情况下,因为当前的元素非0,一定要累加k的值到下一个位置
}
}
}
}
};