给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
【输入】 nums = [0,1,0,3,12] 【输出】 [1,3,12,0,0]
【输入】 nums = [0] 【输出】 [0]
首先,第一个解题思路就是,我们记录一下数字0出现的位置,然后当我们发现有非数字的时候,与数字0的位置互换即可。所以,为了记录数字0出现的位置,我们创建一个数组zeros,其中,zeros[i]表示第i个数字0的下标位置。
然后我们开始遍历整个数组nums,此处需要注意的是,除了当我们发现数字0的时候,需要对zeros赋值之外,当我们执行数字0与非数字0互换操作的时候,数字0所在的新的位置,也需要记录到zeros数组中。
以上就是思路1的解题逻辑,下面我们以nums=[0,1,0,3,12]为例,看一下具体的操作过程:

在思路2中,我们采用移动非0数字的方式,即:我们创建一个指针p,指向nums的第一个元素,即:index=0;然后我们对数组nums进行遍历操作,当发现遍历到的元素是非0数字的话,则执行p指针元素与i指针元素的互换操作,操作完毕后,p指针执行+1操作。当所有nums数组遍历完毕后,就是最终本题的结果啦。下面我们还是以nums=[0,1,0,3,12]为例,看一下具体的操作过程:

在思路3中,我们的关注点也是在非0的数字上,核心算法思想只有一个:将所有非0的数字靠左移动,先不用管0的元素;那么,当所有的非0数字都被移动到左侧之后,那么剩余的所有元素,我们都将其赋值为0即可。下面我们还是以nums=[0,1,0,3,12]为例,看一下具体的操作过程:

class Solution {
public void moveZeroes(int[] nums) {
int[] zeros = new int[nums.length];
Arrays.fill(zeros, -1);
int index = 0, p = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] == 0) zeros[index++] = i;
else if (zeros[p] != -1 && zeros[p] < i) {
nums[zeros[p++]] = nums[i];
nums[i] = 0;
zeros[index++] = i;
}
}
}
}
class Solution {
public void moveZeroes(int[] nums) {
int p = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != 0) {
int temp = nums[p];
nums[p++] = nums[i];
nums[i] = temp;
}
}
}
}class Solution {
public void moveZeroes(int[] nums) {
int p = 0;
for (int i = 0; i < nums.length; i++)
if (nums[i] != 0) nums[p++] = nums[i];
for (int i = p; i < nums.length; i++)
nums[i] = 0;
}