283. 移动零 双指针的三种解法

题目描述

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

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

说明:

  1. 必须在原数组上操作,不能拷贝额外的数组。
  2. 尽量减少操作次数。

 解法1:双指针,第一个0与其后第一个非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记录非0元素应该在的index,i去找非0元素;存在自我交换的重复操作

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