给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums =[0,1,0,3,12]
输出:[1,3,12,0,0]
示例 2:
输入: nums =[0]
输出:[0]
首先想到的应该是当两个连续的数,前面为零,后面不为零时,则两者互换位置
void moveZeroes(int* nums, int numsSize) {
for(int i = 0;i+1 < numsSize ;i++)
{
if(nums[i] == 0 && nums[i+1] != 0)
{
int r = nums[i+1];
nums[i+1] = 0;
nums[i] = r;
}
}
}
但会遇到一个问题,如果循环一次,当两个零连续时,则无法继续,默认为成功
因此需要不断必须循环判断,当全部成立时方可停止循环判断。
void moveZeroes(int* nums, int numsSize) {
while(true)
{
int count =0;
for(int i = 0;i+1 < numsSize ;i++)
{
if(nums[i] == 0 && nums[i+1] != 0)
{
int r = nums[i+1];
nums[i+1] = 0;
nums[i] = r;
count++;
break;
}
}
if(count == 0)
{
break;
}
}
}
但该循环时间复杂度过大,需加以改进
若去除for中的break,则可以一个循环找出多个错误,加快一些时间
void moveZeroes(int* nums, int numsSize) {
while(true)
{
int count =0;
bool isOK = true;
for(int i = 0;i+1 < numsSize ;i++)
{
if(nums[i] == 0 && nums[i+1] != 0)
{
nums[i] = nums[i+1];
nums[i+1] = 0;
isOK = false;
count++;
}
}
if(isOK)
{
break;
}
}
}
void moveZeroes(int* nums, int numsSize) {
int j = 0;
for(int i = 0;i < numsSize ; i++)
{
if(nums[i] != 0)
{
nums[j] = nums[i];
j++;
}
}
while(j < numsSize)
{
nums[j] = 0;
j++;
}
}