説明
numsの配列が与えられた場合、ゼロ以外の要素の相対的な順序を維持しながら、すべてのゼロを配列の最後に移動する関数を記述します。
例:
入力:[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的值到下一个位置
}
}
}
}
};