LEETCODE(力扣)283. 移动零

给定一个数组 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

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

自解

1.双指针for遍历

image
时间、空间,都只能用悲惨来形容。

//从后往前遍历0?
//好像与从前往后没什么区别?不,少遍历了0,更优
//两个指针,一个记录0最靠前的位置,一个进行遍历
void moveZeroes(int* nums, int numsSize) {
    int *p1=nums+numsSize;
    int *pzero=p1;
    int temp=0;
    for(int i=numsSize-2;i>0;i--)
    {
        if(nums[i]==0)
        {
            p1=nums+i;
            while(p1!=pzero-1)
            {
                temp=*p1;
                *p1=*(p1+1);
                *(p1+1)=temp;
                p1++;
            }
            pzero--;
        }
    }
    if(nums[0]==0)
    {
        p1=nums;
        while(p1!=pzero-1)
        {
            temp=*p1;
            *p1=*(p1+1);
            *(p1+1)=temp;
             p1++;
        }
        pzero--;
    }
}

2.双指针分段

image
看了官方解答例子后自写,效果非常好

void swap(int *a,int *b)//交换函数
{
    int temp=0;
    temp=*a;
    *a=*b;
    *b=temp;
}
/*可理解数组分为三段:
处理段 零段 未处理段
左指针:指向处理段后面一个位置,也就是零段第一个零
右指针:记录未处理段的第一个位置,同时对数组进行遍历
当右指针遇到非零数,交换左右两指针值,也就相当将该非零数移动到了处理段
*/
void moveZeroes(int* nums, int numsSize) {
    int *left,*right;
    left=nums;
    right=left;
    while(right<nums+numsSize)//要处理完数组最后一个数才推出循环
    {
        if(*right==0)//右指针指向的数为0
        {
            while(*right==0&&right<nums+numsSize-1)right++;/*遍历到不为零,或者右指针指向数组最后一个数
                                                            -1是为了让右指针不溢到数组外*/
            swap(left,right);//交换,将非零数换到
        }
        else//右指针指向的数非0,直接交换
        {
            swap(left,right);
        }
        right++;
        left++;
    }
}

官方解答

分段的思路,而且更简洁

void swap(int *a, int *b) {
    int t = *a;
    *a = *b, *b = t;
}

void moveZeroes(int *nums, int numsSize) {
    int left = 0, right = 0;
    while (right < numsSize) {
        if (nums[right]) {
            swap(nums + left, nums + right);
            left++;
        }
        right++;
    }
}

作者:力扣官方题解
链接:https://leetcode.cn/problems/move-zeroes/solutions/489622/yi-dong-ling-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
posted @ 2025-04-25 16:19  Osen  阅读(25)  评论(0)    收藏  举报