283.ゼロダブルポインタを移動するための3つのソリューション

タイトル説明

配列が与えられた場合、  ゼロ以外の要素の相対的な順序を維持しながら、numsすべて0を配列の最後に移動する関数を記述します 

例:

入力: [0,1,0,3,12]
出力: [1,3,12,0,0]

説明

  1. 元のアレイを操作する必要があり、追加のアレイをコピーすることはできません。
  2. 操作の数を最小限に抑えます。

 解決策1:ダブルポインター、最初の0はその後の最初の非ゼロと交換されます

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int len = nums.size();
        int first0 = -1;    //无效的初始index

        for (int i = 0; i < len; ++i)
            if (0 == nums[i]) {
                if (first0 < 0)              //寻找第一个0的index
                    first0 = i;
            } else if (first0 >= 0) {        //第一个0已找到,且找到第一个0后面第一个非0元素
                swap(nums[first0], nums[i]); //把第一个0换成非0元素
                i = first0;                  //从刚才第一个0后面重新找新的第一个0
                first0 = -1;
           }
    }
};

解決策2:ダブルポインター、jは非ゼロ要素があるべきインデックスを記録し、iは非ゼロ要素を見つけます;自己交換の繰り返し操作があります

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int len = nums.size();

        int j = 0;                        //遇非0元素自加
        for (int i = 0; i < len; ++i)
            if (nums[i])
                swap(nums[j++], nums[i]); //把非0元素全部换到前面
    }
};

解決策3:自分自身と値を交換しないようにするための解決策2の最適化

//如果元素不为0,i,j跟着一起动。如果元素为零,j记录为零的下标
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int len = nums.size();

        int j = 0;
        for (int i = 0; i < len; ++i)
            if (nums[i]) {
                if (i > j) {
                    nums[j] = nums[i];
                    nums[i] = 0;
                }
                ++j;
            }
    }
};

 

おすすめ

転載: blog.csdn.net/sy_123a/article/details/108327836
おすすめ