过去会遗忘,现在不会

移动零

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

请注意 ,必须在不复制数组的情况下原地对数组进行操作。

 

不用双指针的话直接原地修改数组,count存0的个数,对于不为0的数,如果它前面没有0,就不动,有零的话,就往前移动count位,最后从尾部补充count个0。其实思想也挺像双指针的。

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int count=0;
        int size=nums.size()-1;
for(int i=0;i<nums.size();i++)
{
    if(nums[i]==0)
    {
       count++;
    }
    if(nums[i]!=0&&count!=0)
    {
        nums[i-count]=nums[i];
    }
}
for(int i=0;i<count;i++)
{
nums[size-i]=0;
}

    }
};

双指针的思路和上面其实挺像的,因为上面我遍历数组的时候,移动了不是零的数的位置,之后对这个排好的序列之后的位置一一进行赋值0,这两个步骤有点繁琐。

我想合并一下,遍历的时候兼顾移动位置和赋值0,所以要用到双指针。

具体怎么做呢?

两个指针P1和P2指向开头,P2用于遍历数组,P1指向已排好的序列的末尾,P2不为0就和P1交换一下,P1++,这样就OK了。

代码如下:

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
int p1=0;
int p2=0;
while(p2<nums.size())
{
    if(nums[p2]!=0)
    {
        int temp=nums[p1];
        nums[p1]=nums[p2];
        nums[p2]=temp;
        p2++;p1++;
    }
    else p2++;
}
    }
};

但有没有发现一个问题?P1和P2指向相同位置的时候,它依然进行了交换,显然这是多余的操作。

改进一下,增加个判定条件

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
int p1=0;
int p2=0;
while(p2<nums.size())
{

    if(nums[p2]!=0)
    {
       if(p2>p1)
       {
        int temp=nums[p1];
        nums[p1]=nums[p2];
        nums[p2]=temp;
       }
        p2++;p1++;
    }
    else p2++;
}
    }
};

差不多就这样了。

 

posted on 2023-06-18 02:46  WhatAnyWay  阅读(74)  评论(0)    收藏  举报