问题描述:
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
(来源:leetcode)
解法一:双指针
慢指针用于查询首个0元素位置,快指针用于查询首个0元素后首个非零元素位置,二者交换,循环进行。
void moveZeroes(int* nums, int numsSize){
if(!nums || numsSize < 2) return nums; //特殊情况判断
int p, q;
//初始化p = 第一个0的位置
for(p = 0; p < numsSize; p++){
if(nums[p] == 0) break;
}
//不存在0或第一个0位于最后
if(p >= numsSize - 1) return nums;
//初始化q = 第一个0的下一个位置。第一个零之前全部都是非零,不需要迁移,所以从第一个零往后找需要迁移的非零
else q = p + 1;
// 0 与 非零 交换
while(q < numsSize){
if(nums[p] == 0){ // 找到第一个零
while(q < numsSize){ //查找第一个非零
if(nums[q] != 0){ //查找到,开始交换
nums[p] = nums[q];
nums[q] = 0;
break;
}
q++;
}
}
q++; //下一次查找非零,从上次的位置开始
p++;
}
return nums;
}
解法二:暴力解法
从头开始,查询到一个非零就把它移到前面,依次进行。最后把后面的全变为零。
void moveZeroes(int* nums, int numsSize){
if(!nums || numsSize < 2) return nums; //特殊情况判断
int index = 0, i;
for(i = 0; i < numsSize; i++){ //把所有非零元素前移
if(nums[i] != 0) nums[index++] = nums[i];
}
for(i = index; i < numsSize; i++){ //非迁移位置零
nums[i] = 0;
}
return nums;
}