题目
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:
必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。
解法
依次遍历,使用双指针i,j,如果遇到为0,i先走,j停下,让i去找到下一个不为0的值,赋值给j所在的位置即num[j] = num[i],i所在的位置为赋值0,即num[i] = 0,当又遇到0时,j又会停下,重新被赋值,以此类推,前面值为0的数组索引,被离它最近不为0的值所覆盖
最终,0都在后面。
举两个例子[2,0,1,0,3,12]
- i=j=0,起始位置
- num[0] = 2,不为0,i=1,j=1。
- num[1] = 0, i继续前进,j不动,j=1,i=2。
- num[2] = 1,把num[2]赋值给num[j],num[1] = 1,num[i]被置为0, num[2] = 0, 更新完数组为[2,1,0,0,3,12] ,i和j前进,j=2,i=3
- num[3] = 0,i继续前进,j停止,j=2,i=4
- num[4] = 3,把num[4]赋值给num[j], num[2] = 4,num[i]被置为0,num[4] = 0,更新完数组为[2,1,3,0,0,12],i和j前进,j=3,i=5
- num[5] = 12,把num[5]赋值给num[j], num[3] =12,num[i]被置为0,num[5] = 0,更新完数组为[2,1,3,12,0,0],i和j前进,j=4,i=6
- 结束,最终0被全部挪动到后方。
代码实现
public void moveZeroes(int[] nums) {
int j = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != 0) {
if (i != j) {
nums[j] = nums[i];
nums[i] = 0;
}
j++;
}
}
}