题目描述

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

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

示例 1:

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

示例 2:

输入: nums = [0]
输出: [0]

提示:

1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1

进阶:你能尽量减少完成的操作次数吗?

题目链接:https://leetcode-cn.com/problems/move-zeroes

题目分析

本题可以使用双指针算法来解决

  1. 创建两个指针left和right,开始时分别都指向数组中的第一个元素
  2. 循环遍历数组,其中每次遍历时,right都会向右移动一位
  3. 当right指向的元素不是0时,交换left和right上的元素,然后将left指针向右移动一位,直到right遍历完数组

通过这样的方法,仅需将该数组遍历一遍,就可以保证数组中的0全部移动到数组右侧,时间复杂度为O(n),由于是在原地操作,不需要开辟新的空间,所以空间复杂度为O(1)

62a97885254ce.gif

题解代码

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int left = 0 , right = 0;
        while(right < nums.size()){
            if(nums[right]){//0是false,非零就是true
                //即当right指向的指针为非零时,交换左右指针上的数值
                //然后将左指针向右移动
                swap(nums[left],nums[right]);
                left++;
            }
            right++;
        }
        /**演示示例
         * 0.4.0.8.8//l=0,r=0
         * 0.4.0.8.8//l=0,r=1
         * 4.0.0.8.8//l=1,r=2
         * 4.0.0.8.8//l=1,r=3
         * 4.8.0.0.8//l=2,r=4
         * 4.8.8.0.0//l=3,r=5//退出循环
         */
    }
};

Q.E.D.